Eu encontrei posts muito semelhantes, mas não consigo entender minha expressão regular aqui.
Eu estou tentando escrever uma expressão regular que retorna uma string que está entre duas outras strings. Por exemplo: eu quero obter a string que reside entre as strings "cow" e "milk".
Minha vaca sempre dá leite
retornaria
"sempre dá"
Aqui está a expressão que reuni até agora:
(?=cow).*(?=milk)
No entanto, isso retorna a string "vaca sempre dá".
javascript
regex
string
phil
fonte
fonte
Respostas:
Um lookahead (essa
(?=
parte) não consome nenhuma entrada. É uma asserção de largura zero (assim como verificações de limites e visões atrás).Você deseja uma correspondência regular aqui, para consumir a
cow
parte. Para capturar a parte intermediária, use um grupo de captura (basta colocar a parte do padrão que você deseja capturar entre parênteses):Nenhum lookahead é necessário.
fonte
matched[1]
, e não todo o texto correspondentematched[0]
.([\s\S]*?)
vez de(.*?)
.A solução mais completa que funcionará na grande maioria dos casos é usar um grupo de captura com um padrão de correspondência de pontos preguiçosos . No entanto, um ponto
.
em JavaScript regex não coincide com caracteres de quebra de linha, por isso, o que vai funcionar em 100% dos casos é um[^]
ou[\s\S]
/[\d\D]
/[\w\W]
construções.ECMAScript 2018 e mais recente solução compatível
Nos ambientes JavaScript que suportam o ECMAScript 2018 , o
s
modificador permite.
corresponder qualquer caractere, incluindo caracteres de quebra de linha, e o mecanismo regex suporta lookbehinds de comprimento variável. Então, você pode usar um regex comoEm ambos os casos, a posição atual é verificada
cow
com 1/0 ou mais espaços em branco depois ecow
, em seguida, quaisquer 0 ou mais caracteres possíveis são correspondidos e consumidos (= adicionados ao valor da correspondência) e, em seguida,milk
verificados (com qualquer 1/0 ou mais espaços em branco antes dessa substring).Cenário 1: Entrada de linha única
Este e todos os outros cenários abaixo são suportados por todos os ambientes JavaScript. Veja exemplos de uso na parte inferior da resposta.
cow
é encontrado em primeiro lugar, em seguida, um espaço, em seguida, quaisquer outros do que caracteres de quebra de linha 0+ caracteres, o menor número possível como*?
é um quantificador preguiçoso, são capturados em Grupo 1 e, em seguida, um espaço commilk
deve seguir (e aqueles são combinados e consumidos , também )Cenário 2: Entrada multilinha
Aqui,
cow
e um espaço é correspondido primeiro, em seguida, quaisquer 0 + caracteres o menor possível são correspondidos e capturados no Grupo 1 e, em seguida, um espaçomilk
é correspondido.Cenário 3: correspondências sobrepostas
Se você tem uma string como essa
>>>15 text>>>67 text2>>>
e precisa obter duas correspondências entre>>>
+number
+whitespace
e>>>
, não pode usá-la,/>>>\d+\s(.*?)>>>/g
pois isso encontrará apenas 1 correspondência, porque o>>>
antes67
já foi consumido ao encontrar a primeira correspondência. Você pode usar um lookahead positivo para verificar a presença do texto sem "devorá-lo" (por exemplo, acrescentando à correspondência):Veja a regex demonstração online rendendo
text1
etext2
como Grupo 1 conteúdos encontrados.Consulte também Como obter todas as correspondências sobrepostas possíveis para uma string .
Considerações de desempenho
O padrão de correspondência de pontos preguiçosos (
.*?
) dentro dos padrões regex pode retardar a execução do script se for fornecida uma entrada muito longa. Em muitos casos, a técnica de desenrolar o loop ajuda em maior extensão. Tentando pegar tudo entrecow
emilk
de"Their\ncow\ngives\nmore\nmilk"
, vemos que precisamos apenas corresponder a todas as linhas que não começammilk
, portanto, em vez decow\n([\s\S]*?)\nmilk
podermos usar:Veja a demonstração do regex (se possível
\r\n
, use/cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). Com essa pequena sequência de teste, o ganho de desempenho é insignificante, mas com um texto muito grande, você sentirá a diferença (especialmente se as linhas forem longas e as quebras de linha não forem muito numerosas).fonte
Aqui está um regex que captura o que há entre vaca e leite (sem espaço à esquerda / à direita):
Um exemplo: http://jsfiddle.net/entropo/tkP74/
fonte
.*
.*
remédioRealmente não há necessidade de olhar para trás.
fonte
A resposta escolhida não funcionou para mim ... hmm ...
Basta adicionar espaço após a vaca e / ou antes do leite para aparar os espaços de "sempre dá"
fonte
?<=
não é suportado em Javascript.Consegui o que precisava usando a solução de Martinho Fernandes abaixo. O código é:
Você notará que estou alertando a variável testRE como uma matriz. Isso ocorre porque testRE está retornando como uma matriz, por algum motivo. A saída de:
Alterações para:
fonte
Basta usar a seguinte expressão regular:
fonte
?<=
não é suportado em Javascript. Seria o caminho para fazê-lo embora.Acho regex ser tedioso e demorado, dada a sintaxe. Como você já está usando javascript, é mais fácil fazer o seguinte sem regex:
fonte
Se os dados estiverem em várias linhas, talvez seja necessário usar o seguinte,
Exemplo da Regex 101
fonte
O método match () pesquisa uma string por uma correspondência e retorna um objeto Array.
fonte
Tarefa
Extrair substring entre duas strings (excluindo essas duas strings)
Solução
fonte