Expresión regular para encontrar una cadena incluida entre dos caracteres mientras EXCLUYE los delimitadores

294

Necesito extraer de una cadena un conjunto de caracteres que se incluyen entre dos delimitadores, sin devolver los delimitadores.

Un simple ejemplo debería ser útil:

Objetivo : extraer la subcadena entre corchetes, sin devolver los corchetes.

Cadena base :This is a test string [more or less]

Si uso el siguiente reg. ex.

\ [. *? \]

El partido es [more or less]. Necesito obtener solo more or less(sin los corchetes).

¿Es posible hacer lo?

Diego
fuente

Respuestas:

453

Fácil hecho:

(?<=\[)(.*?)(?=\])

Técnicamente eso es usar lookaheads y lookbehinds. Vea las afirmaciones Lookahead y Lookbehind Zero-Width . El patrón consiste en:

  • está precedido por un [que no está capturado (mirar atrás);
  • un grupo capturado no codicioso. No es codicioso detenerse en la primera]; y
  • es seguido por un] que no se captura (con anticipación).

Alternativamente, puede capturar lo que está entre corchetes:

\[(.*?)\]

y devolver el primer grupo capturado en lugar de la partida completa.

cletus
fuente
138
"Fácil de hacer", LOL! :) Las expresiones regulares siempre me dan dolor de cabeza, tiendo a olvidarlas tan pronto como encuentro las que resuelven mis problemas. Acerca de sus soluciones: el primero funciona como se esperaba, el segundo no, sigue incluyendo los corchetes. Estoy usando C #, tal vez el objeto RegEx tiene su propio "sabor" del motor regex ...
Diego
55
Lo está haciendo porque estás viendo todo el partido en lugar del primer grupo emparejado.
cletus
Muchas gracias, sitio web muy útil! Lo guardaré como referencia. :) Lo siento si he hecho algo de confusión, C # desarrollo no es realmente una de mis habilidades ..
Diego
1
¿Funciona esto si la subcadena también contiene los delimitadores? Por ejemplo, ¿ This is a test string [more [or] less]volvería esto more [or] less?
gnzlbg
1
@gnzlbg no, devolvería "más [o"
MerickOWA
52

Si está utilizando JavaScript , la primera solución provista por cletus (?<=\[)(.*?)(?=\])no funcionará porque JavaScript no admite el operador retrospectivo.

Sin embargo, la segunda solución funciona bien, pero necesita obtener el segundo elemento coincidente.

Ejemplo:

var regex = /\[(.*?)\]/;
var strToMatch = "This is a test string [more or less]";
var matched = regex.exec(strToMatch);

Regresará:

["[more or less]", "more or less"]

Entonces, lo que necesita es el segundo valor. Utilizar:

var matched = regex.exec(strToMatch)[1];

Regresar:

"more or less"
Zanon
fuente
2
¿Qué pasa si hay múltiples coincidencias de [más o menos] en la cadena?
Se han agregado
TheDarkIn1978
19

Solo necesita 'capturar' el bit entre paréntesis.

\[(.*?)\]

Para capturarlo, póngalo entre paréntesis. No dices qué idioma está usando. En Perl, por ejemplo, accedería a esto utilizando la variable $ 1.

my $string ='This is the match [more or less]';
$string =~ /\[(.*?)\]/;
print "match:$1\n";

Otros idiomas tendrán diferentes mecanismos. C #, por ejemplo, usa la clase de colección Match , creo.

Xetius
fuente
Gracias, pero esta solución no funcionó, sigue incluyendo los corchetes. Como escribí en mi comentario a la solución de Cletus, podría ser que el objeto C # RegEx lo interprete de manera diferente. Sin embargo, no soy experto en C #, así que es solo una conjetura, tal vez es solo mi falta de conocimiento. :)
Diego
11

[^\[] Empareja cualquier personaje que no sea [.

+Empareja 1 o más de lo que no es [. Crea grupos de estos partidos.

(?=\])Positiva anticipada ]. Coincide con un grupo que termina ]sin incluirlo en el resultado.

Hecho.

[^\[]+(?=\])

Prueba.

http://regexr.com/3gobr

Similar a la solución propuesta por nulo. Pero el adicional \]no es obligatorio. Como nota adicional, parece \que no es necesario escapar [después de ^. Para facilitar la lectura, lo dejaría en.

No funciona en la situación en que los delimitadores son idénticos. "more or less"por ejemplo.

Stieneee
fuente
8

PHP:

$string ='This is the match [more or less]';
preg_match('#\[(.*)\]#', $string, $match);
var_dump($match[1]);
Powtac
fuente
4

Para eliminar también el uso de []:

\[.+\]
Cătălin Rădoi
fuente
Pero si tiene dos conjuntos [] [], hay un problema con este i.imgur.com/NEOLHZk.png
Cătălin Rădoi
3

Tuve el mismo problema usando regex con bash scripting. Usé una solución de 2 pasos usando tuberías con grep -o aplicando

 '\[(.*?)\]'  

primero luego

'\b.*\b'

Obviamente no es tan eficiente en las otras respuestas, sino una alternativa.

A. Jesús
fuente
3

Este funciona específicamente para el analizador de expresiones regulares de javascript /[^[\]]+(?=])/g

solo ejecuta esto en la consola

var regex = /[^[\]]+(?=])/g;
var str = "This is a test string [more or less]";
var match = regex.exec(str);
match;
nulo
fuente
2

Quería encontrar una cadena entre / y #, pero # a veces es opcional. Aquí está la expresión regular que uso:

  (?<=\/)([^#]+)(?=#*)
techguy2000
fuente
0

Así es como llegué sin '[' y ']' en C #:

        var text = "This is a test string [more or less]";
        //Getting only string between '[' and ']'
        Regex regex = new Regex(@"\[(.+?)\]");
        var matchGroups = regex.Matches(text);
        for (int i = 0; i < matchGroups.Count; i++)
        {
            Console.WriteLine(matchGroups[i].Groups[1]);
        }

El resultado es:

more or less
Jamaxack
fuente
-1

Si necesita extraer el texto sin los corchetes, puede usar bash awk

echo " [hola mundo] " | awk -F'[][]' '{print $2}'

resultado:

hola mundo

Nico
fuente