Expressão regular para encontrar uma string incluída entre dois caracteres enquanto EXCLUINDO os delimitadores


294

Preciso extrair de uma sequência um conjunto de caracteres que são incluídos entre dois delimitadores, sem retornar os próprios delimitadores.

Um exemplo simples deve ser útil:

Alvo : extraia a substring entre colchetes, sem retornar os colchetes.

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

Se eu usar o seguinte reg. ex.

\ [. *? \]

A partida é [more or less]. Eu preciso obter apenas more or less(sem os colchetes).

É possível fazê-lo?


Respostas:


453

Fácil:

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

Tecnicamente, isso é usar lookaheads e lookbehinds. Consulte Lookahead e Lookbehind Zero-Width Assertions . O padrão consiste em:

  • é precedido por um [que não é capturado (lookbehind);
  • um grupo capturado não ganancioso. Não é ganancioso parar no início]; e
  • é seguido por um] que não é capturado (lookahead).

Como alternativa, você pode capturar o que há entre colchetes:

\[(.*?)\]

e retorne o primeiro grupo capturado em vez da partida inteira.


138
"Fácil", LOL! :) Expressões regulares sempre me dão dor de cabeça, tendo a esquecê-las assim que encontro as que resolvem meus problemas. Sobre suas soluções: o primeiro funciona conforme o esperado, o segundo não, continua incluindo os colchetes. Eu estou usando C #, talvez o objeto RegEx tem a sua própria "sabor" do motor regex ...
Diego

5
Está fazendo isso porque você está olhando a partida inteira e não o primeiro grupo correspondente.
Cletus

Muito obrigado, site muito útil! Vou mantê-lo como referência. :) Desculpe se eu fiz alguma confusão, C # desenvolvimento não é realmente uma das minhas habilidades ..
Diego

1
Isso funciona se a substring também contiver os delimitadores? Por exemplo This is a test string [more [or] less], isso retornaria more [or] less?
gnzlbg

1
@gnzlbg não, ele retornaria "more [or" #
MerickOWA

52

Se você estiver usando JavaScript , a primeira solução fornecida pelo cletus (?<=\[)(.*?)(?=\]),, não funcionará porque o JavaScript não suporta o operador lookbehind.

No entanto, a segunda solução funciona bem, mas você precisa obter o segundo elemento correspondente.

Exemplo:

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

Voltará:

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

Então, o que você precisa é o segundo valor. Usar:

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

Para retornar:

"more or less"

2
e se houver várias correspondências de [mais ou menos] na string?


19

Você só precisa 'capturar' o bit entre os colchetes.

\[(.*?)\]

Para capturar, coloque-o entre parênteses. Você não diz qual idioma está usando. No Perl, por exemplo, você acessaria isso usando a variável $ 1.

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

Outras línguas terão mecanismos diferentes. C #, por exemplo, usa a classe de coleção Match , acredito.


Obrigado, mas esta solução não funcionou, ela continua incluindo os colchetes. Como escrevi em meu comentário à solução de Cletus, pode ser que o objeto C # RegEx o interprete de maneira diferente. Não sou especialista em C #, portanto, é apenas uma conjectura, talvez seja apenas a minha falta de conhecimento. :)
Diego

11

[^\[] Corresponde a qualquer caractere que não seja [.

+Combine 1 ou mais do que não é [. Cria grupos dessas correspondências.

(?=\])Lookahead positivo ]. Corresponde a um grupo que termina com ]sem incluí-lo no resultado.

Feito.

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

Prova.

http://regexr.com/3gobr

Semelhante à solução proposta por null. Mas o adicional \]não é necessário. Como uma nota adicional, parece que \não é necessário escapar do [após o ^. Para facilitar a leitura, eu deixaria.

Não funciona na situação em que os delimitadores são idênticos. "more or less"por exemplo.


8

PHP:

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


3

Eu tive o mesmo problema usando regex com scripts bash. Eu usei uma solução em duas etapas usando pipes com grep -o aplicando

 '\[(.*?)\]'  

primeiro, então

'\b.*\b'

Obviamente não é tão eficiente nas outras respostas, mas é uma alternativa.


3

Este funciona especificamente para o analisador de expressões regulares do javascript /[^[\]]+(?=])/g

basta executar isso no console

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

2

Eu queria encontrar uma string entre / e #, mas # às vezes é opcional. Aqui está o regex que eu uso:

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

0

Aqui está como eu fiquei sem '[' e ']' em 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]);
        }

A saída é:

more or less

-1

Se você precisar extrair o texto sem os colchetes, poderá usar o bash awk

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

resultado:

hola mundo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.