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?

Diego
fonte
Relacionados: Regex Jogo todos os caracteres entre duas cordas
Bernhard Barker

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.

cleto
fonte
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"
Zanon
fonte
2
e se houver várias correspondências de [mais ou menos] na string?
As assertivas Lookbehind foram adicionadas ao RegExp no ES2018
TheDarkIn1978 23/05/19
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.

Xetius
fonte
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.

Stieneee
fonte
8

PHP:

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

Para remover também o uso []:

\[.+\]
Cătălin Rădoi
fonte
Mas se você tem dois conjuntos [] [], há um problema com este i.imgur.com/NEOLHZk.png
Cătălin Rădoi
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.

A. Jesús
fonte
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;
nulo
fonte
2

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

  (?<=\/)([^#]+)(?=#*)
techguy2000
fonte
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
Jamaxack
fonte
-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

Nico
fonte