varios tokens separar regulares regular probar expresiones expresion espacio ejemplos delimitadores con comillas blanco alfanumerico regex quotes

tokens - Regex para elegir comas fuera de las comillas



split con varios delimitadores java (6)

No estoy seguro de si esto es posible, así que me dirijo a ti.

Me gustaría encontrar una expresión regular que seleccione todas las comas que caen fuera de los conjuntos de comillas.

Por ejemplo:

''foo'' => ''bar'', ''foofoo'' => ''bar,bar''

Esto seleccionaría la coma simple en la línea 1, después de ''bar'',

Realmente no me importan las comillas simples o dobles.

¿Alguien ha tenido alguna idea? Siento que esto debería ser posible con Readaheads, pero mi expresión regular es demasiado débil.


@SocialCensus, El ejemplo que le diste en el comentario a MarkusQ, donde arrojas ''junto a'', no funciona con el ejemplo que MarkusQ dio justo arriba si cambiamos sam a sam''s : (prueba, una ''coma'', bob, ", sam''s,", aquí) no tiene rival contra (,) (? = (?: [^ "''] | [" |''] [^ "''] ") $). De hecho, el problema en sí mismo "Realmente no me importan las comillas simples versus las dobles", es ambiguo. Debe tener claro lo que quiere decir con una cita con "o con". Por ejemplo, ¿está permitido anidar o no? Si es así, ¿a cuántos niveles? Si solo hay 1 nivel anidado, ¿qué sucede con una coma fuera de la cita anidada interna pero dentro de la cita externa? También debería considerar que las comillas simples ocurren por sí mismas como apóstrofes (es decir, como el contraejemplo que di antes con sam). Finalmente, la expresión regular que usted creó realmente no trata las comillas simples a la par con comillas dobles ya que asume que el último tipo de comillas es necesariamente una comilla doble, y reemplazar la última comilla doble con [''| "] también tiene un problema si el texto no viene con las citas correctas (o si se usan apóstrofes), supongo que probablemente podamos suponer que todas las comillas están delineadas correctamente.

La expresión regular de MarkusQ responde a la pregunta: encuentre todas las comas que tengan un número par de comillas dobles después (es decir, estén fuera de las comillas dobles) y omita todas las comas que tengan un número impar de comillas dobles después (es decir, entre comillas dobles). En general, esta es la misma solución que probablemente desee, pero echemos un vistazo a algunas anomalías. En primer lugar, si alguien deja una comilla al final, esta expresión regular encuentra todas las comas incorrectas en lugar de encontrar las deseadas o no coincide con ninguna. Por supuesto, si falta una comilla doble, todas las apuestas están desactivadas ya que puede no estar claro si la que falta pertenece al final o en su lugar pertenece al principio; sin embargo, hay un caso que es legítimo y donde la expresión regular podría fallar (esta es la segunda "anomalía"). Si ajusta la expresión regular para recorrer las líneas de texto, debe tener en cuenta que al citar varios párrafos consecutivos es necesario que coloque una comilla doble al principio de cada párrafo y omita la cita al final de cada párrafo, excepto en el fin del último párrafo. Esto significa que en el espacio de esos párrafos, la expresión regular fallará en algunos lugares y tendrá éxito en otros.

En http://en.wikipedia.org/wiki/Quotation_mark se pueden encontrar ejemplos y breves discusiones sobre citas de párrafos y de citas anidadas.


Esto hará coincidir cualquier cadena hasta e incluyendo el primer "," no citado. ¿Es eso lo que quieres?

/^([^"]|"[^"]*")*?(,)/

Si los quiere a todos (y como un contraejemplo para el tipo que dijo que no era posible), podría escribir:

/(,)(?=(?:[^"]|"[^"]*")*$)/

que coincidirá con todos ellos. Así

''test, a "comma,", bob, ",sam,",here''.gsub(/(,)(?=(?:[^"]|"[^"]*")*$)/,'';'')

reemplaza todas las comas que no están dentro de comillas con punto y coma, y ​​produce:

''test; a "comma,"; bob; ",sam,";here''

Si necesita que funcione a través de saltos de línea simplemente agregue el indicador m (multilínea).


La respuesta de MarkusQ funcionó muy bien para mí durante aproximadamente un año, hasta que no fue así. Acabo de recibir un error de desbordamiento de pila en una línea con aproximadamente 120 comas y 3682 caracteres en total. En Java, así:

String[] cells = line.split("[/t,](?=(?:[^/"]|/"[^/"]*/")*$)", -1);

Aquí está mi reemplazo extremadamente poco elegante que no acumula desbordamiento:

private String[] extractCellsFromLine(String line) { List<String> cellList = new ArrayList<String>(); while (true) { String[] firstCellAndRest; if (line.startsWith("/"")) { firstCellAndRest = line.split("([/t,])(?=(?:[^/"]|/"[^/"]*/")*$)", 2); } else { firstCellAndRest = line.split("[/t,]", 2); } cellList.add(firstCellAndRest[0]); if (firstCellAndRest.length == 1) { break; } line = firstCellAndRest[1]; } return cellList.toArray(new String[cellList.size()]); }


Las expresiones regulares a continuación coincidirían con todas las comas que están presentes fuera de las comillas dobles,

,(?=(?:[^"]*"[^"]*")*[^"]*$)

DEMO

O (PCRE solamente)

"[^"]*"(*SKIP)(*F)|,

"[^"]*" coincide con el bloque doble citado. Es decir, en esta entrada buz,"bar,foo" , esta expresión regular coincidiría con "bar,foo" solamente. Ahora lo siguiente (*SKIP)(*F) hace que la coincidencia falle. Luego pasa al patrón que estaba al lado del símbolo e intenta hacer coincidir los caracteres de la cadena restante. Es decir, en nuestra salida , lado del patrón coincidirá solo con la coma que estaba justo después de buz cuenta que esto no coincidirá con la coma que estaba presente entre comillas dobles, porque ya hacemos que la parte con comillas dobles se salte.

DEMO

La expresión regular a continuación coincidiría con todas las comas que están presentes dentro de las comillas dobles,

,(?!(?:[^"]*"[^"]*")*[^"]*$)

DEMO


Prueba esta expresión regular:

(?:"(?:[^//"]+|//(?:////)*[//"])*"|''(?:[^//']+|//(?:////)*[//'])*'')/s*=>/s*(?:"(?:[^//"]+|//(?:////)*[//"])*"|''(?:[^//']+|//(?:////)*[//'])*'')/s*,

Esto también permite cadenas como " ''foo/'bar'' => ''bar//', ".


Si bien es posible hackearlo con una expresión regular (y me gusta abusar de expresiones regulares tanto como el siguiente tipo), tarde o temprano te meterás en problemas tratando de manejar subcadenas sin un analizador más avanzado. Las posibles formas de meterse en problemas incluyen comillas mixtas y citas escapadas.

Esta función dividirá una cadena en comas, pero no esas comas que están dentro de una cadena de una o dos comillas. Se puede ampliar fácilmente con caracteres adicionales para usar como comillas (aunque los pares de caracteres como «» necesitarían algunas líneas más de código) e incluso le dirá si olvidó cerrar una cita en sus datos:

function splitNotStrings(str){ var parse=[], inString=false, escape=0, end=0 for(var i=0, c; c=str[i]; i++){ // looping over the characters in str if(c===''//'){ escape^=1; continue} // 1 when odd number of consecutive / if(c==='',''){ if(!inString){ parse.push(str.slice(end, i)) end=i+1 } } else if(splitNotStrings.quotes.indexOf(c)>-1 && !escape){ if(c===inString) inString=false else if(!inString) inString=c } escape=0 } // now we finished parsing, strings should be closed if(inString) throw SyntaxError(''expected matching ''+inString) if(end<i) parse.push(str.slice(end, i)) return parse } splitNotStrings.quotes="''/"" // add other (symmetrical) quotes here