Regex Corresponde a todos os caracteres entre duas cadeias


435

Exemplo: "Esta é apenas uma sentença simples".

Eu quero combinar todos os caracteres entre "This is" e "sentença". Quebras de linha devem ser ignoradas. Não consigo descobrir a sintaxe correta.


11
Você pode indicar em que ambiente está usando o Regex. Pode haver diferenças dependendo do que você quer dizer com "ignorar" quebras de linha.
Andrew Barber

Respostas:


647

Por exemplo

(?<=This is)(.*)(?=sentence)

Regexr

Usei o lookbehind (?<=)e o antecipei (?=)para que "This is" e "sentença" não sejam incluídos na correspondência, mas isso depende do seu caso de uso, você também pode simplesmente escrever This is(.*)sentence.

O importante aqui é que você ative o modo "dotall" do seu mecanismo de expressão regular, para que ele .corresponda à nova linha. Mas como você faz isso depende do seu mecanismo de expressão regular.

A próxima coisa é se você usar .*ou .*?. O primeiro é ganancioso e corresponderá até a última "sentença" em sua string, o segundo será preguiçoso e corresponderá até a próxima "sentença" em sua string.

Atualizar

Regexr

This is(?s)(.*)sentence

Onde o (? S) ativa o modificador dotall, fazendo a .correspondência dos caracteres da nova linha.

Atualização 2:

(?<=is \()(.*?)(?=\s*\))

está correspondendo ao seu exemplo "Esta é uma sentença (simples)". Veja aqui no Regexr


@ Chris, desculpe, eu tive que procurar isso. Entendo isso correto e This is(?s)(.*)sentenceestaria funcionando?
stema 24/05

@stema: Sim, isso deve funcionar para ativar o modo "dot all" na maioria das bibliotecas regex.
Tchrist 24/05

1
Isso resolveu principalmente o meu problema, mas como incluo um caractere de espaço em branco no meu padrão? Tentei o seguinte: "(. *?) ())" Para corresponder ao ")" no final de uma sequência, mas não funcionou.
0xbadf00d

28
Apenas uma nota - regexr diz agora que lookbehind não é suportada em javascript
Kovo

2
Existe uma maneira de lidar com instâncias repetidas dessa divisão em um bloco de texto? Por exemplo: "Esta é apenas uma sentença simples. Aqui estão algumas coisas adicionais. Esta é apenas uma sentença simples. E aqui estão mais algumas coisas. Esta é apenas uma sentença simples.". Atualmente, ele corresponde à cadeia inteira, em vez de cada instância.
jzadra

181

Quantificador preguiçoso necessário

Ressuscitar esta pergunta porque a expressão regular na resposta aceita não me parece correta. Por quê? Porque

(?<=This is)(.*)(?=sentence)

vai combinar my first sentence. This is my secondemThis is my first sentence. This is my second sentence.

Veja a demonstração .

Você precisa de um quantificador lento entre as duas visões. A adição de a ?torna a estrela preguiçosa.

Isso corresponde ao que você deseja:

(?<=This is).*?(?=sentence)

Veja a demonstração . Eu removi o grupo de captura, o que não era necessário.

Modo DOTALL para coincidir com quebras de linha

Observe que, na demonstração, o "ponto corresponde ao modo de quebras de linha" (aka) dot-all está definido (veja como ativar o DOTALL em vários idiomas ). Em muitos tipos de expressões regulares, você pode configurá-lo com o modificador online (?s), transformando a expressão em:

(?s)(?<=This is).*?(?=sentence)

Referência


Você está correto sobre o grupo de captura. Não sei por que fiz isso. Mas a diferença entre .*e .*?também é explicada na minha resposta (o parágrafo antes de "Atualizar"). Portanto, não acho que minha resposta esteja incorreta.
stema

2
@stema Desculpa as críticas, enquanto cruzava algumas das suas respostas ontem, essa é a única que me fez estremecer. :) Eu suavizei a primeira linha de is incorrectpara doesn't seem quite correct to me... Espero que isso não faça você se mexer, provavelmente apenas uma diferença de percepção sobre qual deve ser a expressão regular para uma resposta de tráfego intenso.
Zx81

39

Tente This is[\s\S]*sentence, funciona em javascript


como executar uma pesquisa preguiçosa dessa maneira?
AGamePlayer

4
@AwQiruiGuo mesmo que acima. [\s\S]*?(também chamado: wildcard não-ganancioso)
phil294


13

usa isto: (?<=beginningstringname)(.*\n?)(?=endstringname)


Não sei por que todos os votos até, isso permite 0-1 quebras de linha, e a quebra de linha deve ser imediatamente antesendstringname
OGHaza

Achei útil remover o início das linhas de log (registro de data e hora, etc.). Eu usei nova linha para a string inicial e "at" para a string final.
Stan

2

Caso alguém esteja procurando um exemplo disso dentro de um contexto Jenkins. Ele analisa o build.log e, se encontrar uma correspondência, falha na compilação com a correspondência.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

node{    
    stage("parse"){
        def file = readFile 'build.log'

        def regex = ~"(?s)(firstStringToUse(.*)secondStringToUse)"
        Matcher match = regex.matcher(file)
        match.find() {
            capturedText = match.group(1)
            error(capturedText)
        }
    }
}


1

Isso funcionou para mim (estou usando o código VS ):

para: This is just\na simple sentence

Usar: This .+ sentence


0

Texto sublime 3x

No texto sublime, você simplesmente escreve as duas palavras que deseja manter, por exemplo, no seu caso, é

"Isto é" e "sentença"

e você escreve. * entre

ie This is .* sentence

e isso deve te fazer bem


Não tenho certeza se a pergunta é sobre como fazer isso no texto sublime, mas funciona principalmente em texto sublime. Não funciona quando ocorre uma quebra de linha entre "Isto é" e "Sentença". Além disso, o texto sublime também seleciona "Isto é" e "Sentença", em vez de apenas o texto entre essas duas cadeias.
Dylan Kinnett

0

Aqui está como eu fiz:
Isso foi mais fácil para mim do que tentar descobrir o regex específico necessário.

int indexPictureData = result.IndexOf("-PictureData:");
int indexIdentity = result.IndexOf("-Identity:");
string returnValue = result.Remove(indexPictureData + 13);
returnValue = returnValue + " [bytecoderemoved] " + result.Remove(0, indexIdentity); ` 

0

para uma pesquisa rápida no VIM, você pode usar no prompt do Vim Control: / This is. * \ _. * sentença


0

Eu cheguei aqui na minha pesquisa por regex para converter essa sintaxe de impressão entre "string" de impressão, em Python2 em scripts antigos com: print ("string"), para Python3. Funciona bem; caso contrário, use 2to3.py para conversões adicionais. Aqui está a minha solução para os outros:

Experimente no Regexr.com (por algum motivo não funciona no NP ++):

find:     (?<=print)( ')(.*)(')
replace: ('$2')

para variáveis:

(?<=print)( )(.*)(\n)
('$2')\n

para rótulo e variável:

(?<=print)( ')(.*)(',)(.*)(\n)
('$2',$4)\n

Como substituir toda a "string" de impressão no Python2 pela print ("string") do Python3?


0

RegEx para combinar tudo entre duas cadeias usando a abordagem Java.

List<String> results = new ArrayList<>(); //For storing results
String example = "Code will save the world";

Vamos usar objetos Pattern e Matcher para usar RegEx (. ?) * .

Pattern p = Pattern.compile("Code "(.*?)" world");   //java.util.regex.Pattern;
Matcher m = p.matcher(example);                      //java.util.regex.Matcher;

Como o Matcher pode conter mais de uma correspondência, precisamos repetir os resultados e armazená-los.

while(m.find()){   //Loop through all matches
   results.add(m.group()); //Get value and store in collection.
}

Este exemplo conterá apenas "salvará a" palavra, mas no texto maior provavelmente encontrará mais correspondências.

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.