2010-06-02 22 views
8

Estoy buscando una expresión regular para que coincida con los literales de cadena en el código fuente de Java.Emparejar correctamente una cadena de Java literal

¿Es posible?

private String Foo = "A potato"; 
private String Bar = "A \"car\""; 

Mi intención es reemplazar todas las cadenas dentro de otra cadena por otra cosa. Usando:

String A = "I went to the store to buy a \"coke\""; 
String B = A.replaceAll(REGEX,"Pepsi"); 

Algo como esto.

+0

Sí. ¿Puedes proporcionar un fragmento de código fuente para explicar mejor lo que buscas? – Wangnick

Respuesta

4

Ok. Entonces, ¿qué quiere es buscar, dentro de una cadena, una secuencia de caracteres que comience y termine con comillas dobles?

String bar = "A \"car\""; 
    Pattern string = Pattern.compile("\".*?\""); 
    Matcher matcher = string.matcher(bar); 
    String result = matcher.replaceAll("\"bicycle\""); 

Observe el patrón no codicioso .*?.

+1

¿Y si la cadena dentro de la cadena también tiene comillas? –

+0

Sí. Entonces que. ¿Cómo sabes dónde termina? En este caso, debe asegurarse de que las comillas de la cadena interna se escapen de alguna manera al construir la cadena externa, trate esto en su cadena de reemplazo y luego vuelva a desenterrar el resultado cuando sea necesario. Una forma posible de escapar de las cotizaciones es, por ejemplo, duplicarlas. – Wangnick

+0

Si duplica las comillas para escapar de ellas, su expresión regular se vuelve engañosa. Probablemente, una mejor sea para definir otro personaje para introducir el escape (por ejemplo, y como en html), y luego para escapar de todas las ocurrencias de ese también. – Wangnick

1

Puede ver diferentes generadores de analizadores para Java y su expresión regular para el elemento de gramática StringLiteral.

Aquí es un example from ANTLR:

StringLiteral 
    : '"' (EscapeSequence | ~('\\'|'"'))* '"' 
    ; 
+0

Supongo que querrá evitar atrapar '//" hello "' – aioobe

+0

Siempre tuve la impresión de que la mayoría de los compiladores de Java procesaban comentarios antes y solo entonces buscaban todo lo demás. Pero podría estar equivocado acerca de esto. – Uri

+0

Mi problema con esta respuesta es que no estoy muy cómodo con las gramáticas. –

-1

Usted no dice qué herramienta que está utilizando para hacer su hallazgo (perl sed editor de texto Ctrl-F, etc, etc?). Pero una expresión regular general sería:

\".*?\" 

Editar: esta es una respuesta rápida & sucia, y no hacer frente a las cotizaciones escapado, comentarios, etc

+3

¿Qué pasa con las comillas que se han escapado en la cadena? – Joe

+0

Me imagino que es Java regex, teniendo en cuenta la etiqueta Java. – corsiKa

+0

Esto también coincidirá con las comillas en los comentarios. Esto no debería tener falsos negativos, pero definitivamente tendrá falsos positivos. –

-1

Utilice esta:

String REGEX = "\"[^\"]*\""; 

probado con

String A = "I went to the store to buy a \"coke\" and a box of \"kleenex\""; 
String B = A.replaceAll(REGEX,"Pepsi"); 

se obtiene la siguiente 'B'

I went to the store to buy a Pepsi and a box of Pepsi 
+0

Pruébelo en esta entrada: '" La comilla doble es \ "aquí -> \" <- aquí \ "" '. – seh

+0

@seh, ¿cuál consideraría una salida correcta para su ejemplo? La pregunta original no exige citas -within-quotes, comillas sin pares, o incluso cadenas de comillas múltiples, para el caso ... – tucuxi

+0

esperaría 'La comilla doble es" Pepsi "', por mi lectura de la pregunta, porque tomo un " literal de cadena "para significar cualquier contenido que sea válido en la sintaxis de lenguaje de host para definir una cadena. Tiene razón en que la pregunta original no solicitó la cobertura de los casos más difíciles, mencionando solo cadenas dentro de cadenas, pero también creo que eso es lo que hace que el problema sea interesante. Recuerdo que * Mastering Regular Expressions * de Jeffrey Friedl era legendario por haber establecido finalmente el máximo afinador de cadenas de doble cita, por no mencionar su homólogo de direcciones de correo electrónico RFC 822. Ese es el punto de referencia – seh

2

esta expresión regular puede manejar comillas dobles, así (NOTA: Perl sintaxis extendida):

" 
[^\\"]* 
(?: 
    (?:\\\\)* 
    (?: 
     \\ 
     " 
     [^\\"]* 
    )? 
)* 
" 

se define que cada uno "tiene que tener una cantidad impar de escape \ antes de que

tal vez es posible para embellecer esto un poco, pero funciona en esta forma

+0

Este patrón viene MUY cerca de lo que yo ¡necesario! Sin embargo, ¿qué ocurre si la cadena incrustada contiene, digamos, una URL? Por ejemplo: "URL String: \" http: \/\/www.google.com \ ";", esta expresión se rompe, capturando solo ";". (He estado rascándome la cabeza con esto durante horas) – TekuConcept

Cuestiones relacionadas