2011-12-12 11 views
5

tengo la siguiente cadena:Perl dividida y expresión regular

'100% California Grown Olives, Water, Salt And Ferrous Gluconate (An,Iron, Derivative),asasd, sadasda' 

Estoy tratando de dividirlo por /,/ pero sólo si no es soportes en el interior, por ejemplo, en este caso, el resultado debería ser :

100% California Grown Olives 
Water 
Salt And Ferrous Gluconate (An,Iron, Derivative) 
asasd 
sadasda 

gracias,

+1

¿Existe la posibilidad de paréntesis anidados? Si es así, es posible que las expresiones regulares no se ajusten a la factura. –

+1

no, no es posible. solo par único de paréntesis, o pareja pero NO anidado – snoofkin

Respuesta

11
@result = split(m/,(?![^()]*\))/, $subject); 

T sus divisiones en una coma solo si el siguiente paréntesis siguiente (si existe) no es un paréntesis de cierre. Como Jack Maney notó correctamente, esto puede llevar al fracaso si se pueden producir paréntesis anidados.

Explicación:

,  # Match a comma. 
(?!  # Assert that it's impossible to match... 
[^()]* # any number of non-parenthesis characters 
\)  # followed by a closing parenthesis 
)  # End of lookahead assertion 
1

En primer lugar, debe decidir lo que constituye parens, y si se pueden anidar. (para esta respuesta, asumiré que pueden ser). Luego hay que eliminar esos bloques paren a partir del texto y reemplazarlo con un marcador de posición:

my @parens; 
$str =~ s/(\((?: (?0)|[^()])* \))/push @parens, $1; "PARENS_$#parens"/gex; 

Así que ahora lo que queda es algo que se parece:

'100% California Grown Olives, Water, Salt And Ferrous Gluconate PAREN_0,asasd, 
sadasdas.' 

y es simple ahora para dividir en comas. Luego, en cada una de las piezas divididas, escanee tokens PAREN_\d+ y reemplácelos con los del conjunto @parens. Es posible que necesite utilizar un nombre de marcador de posición más único en función de su contenido fuente.

Algo así como:

s/PARENS_(\d+)/$parens[$1]/ge for my @segs = split /,\s*/ => $str; 

say for @segs; 

que, por ejemplo cadena:

my $str = "foo (b,a,r), baz (foo, (bar), baz), biz"; 

impresiones:

foo (b,a,r) 
baz (foo, (bar), baz) 
biz 
+0

No creo que deba evaluar '$ parens [$ 1]'. – TLP

0

Puede que le resulte más fácil construir una expresión regular para lo que quiere partido, en lugar de lo que desea eliminar. (Esto supone que no desea limitar el número de coincidencias).

Cuestiones relacionadas