2011-08-28 15 views
5

Estoy usando perl y necesito dividir cadenas de nombres de autor delimitados por comas, así como un último "y". Los nombres se forman como primer nombre y apellido, con este aspecto:Necesita ayuda para dividir esta cadena de nombres (nombre y apellido pares delimitados por comas y "y")

$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); 

quisiera sólo para dividir los nombres completos en elementos de una matriz, como lo que split() haría, por lo que el @data array sería contener, por ejemplo:

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

sin embargo, el problema es que no hay una coma entre los dos últimos nombres en las listas. Cualquier ayuda sería apreciada.

+0

¿Qué vas a hacer con "nombres" como "Joe Smith, MD and Mary and Joe Smith"? – tadmc

+0

nota, no usa '@data [1]' sino más bien '$ data [1]'. Como solo está utilizando un elemento, es un escalar. –

Respuesta

10

Se puede usar un simple alternancia en su expresión regular para dividir:

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

Por ejemplo:

$ 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 

Si también tiene que lidiar con el Oxford Com ma (es decir "Esto, aquello y lo otro"), entonces se podría utilizar

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

Por ejemplo:

$ 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 

Gracias a stackoverflowuser2010 para anotar este caso.

Querrá el \s*,\s*and\s+ al principio de mantener las otras ramas de la alternancia de la división de la coma o "y" primero, this order appears to be guaranteed as well:

Alternativas son juzgados de izquierda a derecha, por lo que la La primera alternativa que se encuentra para la cual toda la expresión coincide, es la que se elige.

+3

o simplemente podría usar | sin grupo ... – ysth

+0

@ysth: Usted puede adivinar que comencé con '\ s * (...) \ s *' y lo refine para eliminar la maldad. –

+0

¿Cuál es el beneficio del grupo en esta solución en lugar de solo el | como @yslth sugirió? – cftarnas

4

Antes split, reemplace and con un ,:

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