2011-08-28 8 views
5

Używam perla i muszę rozdzielić ciągi nazwisk autorów rozdzielanych przecinkami, a także ostatnie "i". Nazwy są tworzone jak imię i nazwisko, patrząc tak:Potrzebujesz pomocy w dzieleniu tego ciągu nazw (pary imion i nazw oddzielone przecinkami i "i")

$string1 = "Joe Smith, Jason Jones, Jane Doe and Jack Jones"; 
$string2 = "Joe Smith, Jason Jones, Jane Doe, and Jack Jones"; 
$string3 = "Jane Doe and Joe Smith"; 
# Next line doesn't work because there is no comma between last two names 
@data = split(/,/, $string1); 

Chciałbym podzielić pełne nazwy do elementów tablicy, jak to, co podzielone() byłoby zrobić tak, że @data tablica zawiera, na przykład:

@data[0]: "Joe Smith" 
@data[1]: "Jason Jones" 
@data[2]: "Jane Doe" 
@data[3]: "Jack Jones" 

Problem polega jednak na tym, że nie ma przecinków między dwiema ostatnimi nazwami na listach. Każda pomoc będzie doceniona.

+0

Co zrobisz z "imionami" jak "Joe Smith, MD, Mary i Joe Smith"? – tadmc

+0

uwaga, nie używa się '@data [1]', ale raczej '$ data [1]'. Ponieważ używasz tylko jednego elementu, jest to skalar. –

Odpowiedz

10

Można użyć prostego naprzemiennie w wyrażeniu regularnym do rozłamu:

my @parts = split(/\s*,\s*|\s+and\s+/, $string1); 

Na przykład:

$ perl -we 'my $string1 = "Joe Smith, Jason Jones, Jane Doe and Jack Jones";print join("\n",split(/\s*,\s*|\s+and\s+/, $string1)),"\n"' 
Joe Smith 
Jason Jones 
Jane Doe 
Jack Jones 

$ perl -we 'my $string2 = "Jane Doe and Joe Smith";print join("\n",split(/\s*,\s*|\s+and\s+/, $string2)),"\n"' 
Jane Doe 
Joe Smith 

Jeśli masz także do czynienia z Oxford Com ma (tj. "To, że i inne rzeczy"), a następnie można użyć

my @parts = split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $string1); 

Na przykład:

$ perl -we 'my $s = "Joe Smith, Jason Jones, Jane Doe, and Jack Jones";print join("\n",split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $s)),"\n"' 
Joe Smith 
Jason Jones 
Jane Doe 
Jack Jones 

$ perl -we 'my $s = "Joe Smith, Jason Jones, Jane Doe and Jack Jones";print join("\n",split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $s)),"\n"' 
Joe Smith 
Jason Jones 
Jane Doe 
Jack Jones 

$ perl -we 'my $s = "Joe Smith and Jack Jones";print join("\n",split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $s)),"\n"' 
Joe Smith 
Jack Jones 

Dzięki stackoverflowuser2010 dla zauważyć tę sprawę.

Będziesz chcą \s*,\s*and\s+ na początku, aby utrzymać pozostałe gałęzie naprzemiennie z podziału na przecinek lub „i” pierwszy this order appears to be guaranteed as well:

Alternatywy są sprawdzane od strony lewej do prawej, a więc pierwszą znalezioną alternatywą, dla której pasuje całe wyrażenie, jest ten, który został wybrany.

+3

lub możesz po prostu użyć | bez grupy ... – ysth

+0

@ysth: Możesz zgadnąć, że zacząłem od '\ s * (...) \ s *' i udoskonaliłem je, aby usunąć zło. –

+0

Jakie korzyści daje grupa w tym rozwiązaniu, a nie tylko | jak zasugerował @yslth? – cftarnas

4

Przed split wymienić and z ,:

$string1 =~ s{\s+and\s+}{,}g;