2010-10-06 14 views
9

cadena que se divideSeparar una cadena que tiene la secuencia de escape usando expresiones regulares en Java

abc:def:ghi\:klm:nop 

cadena debería dividirse en base a ":" "\" es el carácter de escape. Por lo tanto, "\:" no debe tratarse como token.

división (":") da

[abc] 
[def] 
[ghi\] 
[klm] 
[nop] 

Producto previsto es array de cadenas

[abc] 
[def] 
[ghi\:klm] 
[nop] 

¿Cómo puede la \: ser ignorado

+0

También es posible lo siguiente: 'abc:" def: ghi ": jkl'? –

Respuesta

16

Utilice un look-behind assertion:

split("(?<!\\\\):") 

Esto solo coincidirá si no existe el número anterior \. Se requiere el uso de doble escape \\\\, ya que se requiere uno para la declaración de cadena y uno para la expresión regular.

Sin embargo, tenga en cuenta que esto no le permitirá escapar de las barras diagonales inversas, en el caso de que quiera permitir que un token termine con una barra invertida. Para hacer esto, usted tendrá que reemplazar primero todas las barras invertidas dobles con

string.replaceAll("\\\\\\\\", ESCAPE_BACKSLASH) 

(donde ESCAPE_BACKSLASH es una cadena que no va a ocurrir en su entrada) y luego, después de la división usando la afirmación de observación detrás, reemplazar la cadena ESCAPE_BACKSLASH con una barra invertida sin escapar con

token.replaceAll(ESCAPE_BACKSLASH, "\\\\") 
0

Gumbo fue correcta utilizando un look-behind assertion, pero en caso de que su cadena contiene el carácter de escape escapado (por ejemplo \\) justo en frente de una coma, la división podría romper. Vea este ejemplo:

test1\,test1,test2\\,test3\\\,test3\\\\,test4

Si lo hace un simple vistazo dividida subyacente para (?<!\\), como se sugiere Gumbo, la cadena se hace dividió en dos partes solamente test1\,test1 y test2\\,test3\\\,test3\\\\,test4. Esto se debe a que el look-behind simplemente verifica un personaje para el personaje de escape. Lo que realmente sería correcto, si la secuencia se divide en comas y comas precedidas por un número par de caracteres de escape.

Para lograr esto un poco más compleja (doble) mira-detrás es necesaria la expresión:

(?<!(?<![^\\]\\(?:\\{2}){0,10})\\),

El uso de esta expresión regular más complejo en Java, de nuevo requiere para escapar de todo \ por \\. Por lo que esta debe ser una respuesta más sofisticado a su pregunta:

"any comma separated string".split("(?<!(?<![^\\\\]\\\\(?:\\\\{2}){0,10})\\\\),"); 

Nota: Java no soporta repeticiones infinitas dentro de lookbehinds. Por lo tanto, solo se verifican hasta 10 caracteres de repetición de escape doble utilizando la expresión {0,10}. Si es necesario, puede aumentar este valor ajustando el último número.

Cuestiones relacionadas