Por exemplo, este regex
(.*)<FooBar>
irá corresponder:
abcde<FooBar>
Mas como faço para corresponder em várias linhas?
abcde
fghij<FooBar>
Por exemplo, este regex
(.*)<FooBar>
irá corresponder:
abcde<FooBar>
Mas como faço para corresponder em várias linhas?
abcde
fghij<FooBar>
Respostas:
Depende do idioma, mas deve haver um modificador que você pode adicionar ao padrão regex. No PHP é:
/(.*)<FooBar>/s
O s no final faz com que o ponto corresponda a todos os caracteres, incluindo novas linhas.
s
modificador. Em vez disso, faça [^]*
o mesmo efeito.
m
modificador
Tente o seguinte:
((.|\n)*)<FooBar>
Diz basicamente "qualquer caractere ou uma nova linha" repetida zero ou mais vezes.
((.|\n|\r)*)<FooBar>
[\s\S]*
ou (?s).*
.
A questão é: o .
padrão pode corresponder a qualquer caractere? A resposta varia de mecanismo para mecanismo. A principal diferença é se o padrão é usado por uma biblioteca de expressões regulares POSIX ou não POSIX.
Nota especial sobre padrões de lua: eles não são considerados expressões regulares, mas .
correspondem a qualquer caractere igual aos mecanismos baseados no POSIX.
Outra nota sobre Matlab e oitava: .
corresponde a qualquer caractere por padrão ( demo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
( tokens
contém um abcde\n fghij
item).
Além disso, em todos impulsogramáticas regex, o ponto corresponde a quebras de linha por padrão. A gramática ECMAScript do Boost permite desativar isso com regex_constants::no_mod_m
( fonte ).
Quanto a oráculo(é baseado em POSIX), use a n
opção ( demo ):select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Mecanismos baseados em POSIX :
Um mero .
já corresponde a quebras de linha, não há necessidade de usar nenhum modificador, consultebater( demo ).
o tcl( demo ),postgresql( demo ),r(TRE, motor de base R padrão sem perl=TRUE
, para a base R com perl=TRUE
ou para stringr / Stringi padrões, use o (?s)
modificador de linha) ( demonstração ) também tratar .
da mesma maneira.
No entanto , a maioria das ferramentas baseadas no POSIX processa a entrada linha por linha. Portanto, .
não corresponde às quebras de linha apenas porque elas não estão no escopo. Aqui estão alguns exemplos de como substituir isso:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
( H;1h;$!d;x;
coloca o arquivo na memória). Se for necessário incluir linhas inteiras, sed '/start_pattern/,/end_pattern/d' file
(a remoção do início terminará com as linhas correspondentes incluídas) ou sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(com as linhas correspondentes excluídas) poderá ser considerada.perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
( -0
coloca o arquivo inteiro na memória, -p
imprime o arquivo após aplicar o script fornecido por -e
). Observe que usar -000pe
irá arrastar o arquivo e ativar o 'modo de parágrafo' onde o Perl usa novas linhas consecutivas ( \n\n
) como separador de registros.grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Aqui, z
habilita o slurping de arquivo, (?s)
habilita o modo DOTALL para o .
padrão , habilita o modo sem distinção entre (?i)
maiúsculas e minúsculas, \K
omite o texto correspondente até agora, *?
é um quantificador lento, (?=<Foobar>)
corresponde ao local antes <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
( M
ativa o slurping de arquivo aqui). Nota pcregrep
é uma boa solução para grep
usuários de Mac OS .Mecanismos não baseados em POSIX :
s
modificador PCRE_DOTALL : preg_match('~(.*)<Foobar>~s', $s, $m)
( demo )RegexOptions.Singleline
sinalizador ( demo ): var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
a opção embutida:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
modificador (ou (?s)
versão embutida no início) ( demo ):/(.*)<FooBar>/s
re.DOTALL
(ou re.S
) bandeiras ou (?s)
modificador inline ( demonstração ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(e, em seguida if m:
, print(m.group(1))
)Pattern.DOTALL
modificador (ou (?s)
sinalizador embutido ) ( demo ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
modificador dentro do padrão ( demo ):regex = /(?s)(.*)<FooBar>/
(?s)
modificador ( demo ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
ou soluções alternativas [\d\D]
/ [\w\W]
/ [\s\S]
( demo ):s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Use [\s\S]
ou as soluções alternativas JS ( demo ):regex rex(R"(([\s\S]*)<FooBar>)");
vba vbscript- Use a mesma abordagem que em JavaScript ([\s\S]*)<Foobar>
,. ( OBSERVAÇÃO : Às vezes, considera-se erroneamente que a MultiLine
propriedade do
RegExp
objeto é a opção para permitir a .
correspondência entre quebras de linha, enquanto, na verdade, apenas altera o comportamento ^
e $
para corresponder ao início / fim de linhas em vez de cadeias de caracteres , o mesmo que no regex JS ) comportamento.)
rubi- Use o modificador /m
MULTILINE ( demo ):s[/(.*)<Foobar>/m, 1]
(?s)
: regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
( demo )stringr
/ stringi
regex que são alimentadas com o mecanismo regex ICU, também use (?s)
: stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
( demo )(?s)
no início ( demo ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
ou (mais fácil) passe o (?s)
modificador em linha para o padrão:let rx = "(?s)(.*)<Foobar>"
(?s)
funciona da maneira mais fácil, mas eis como a opção pode ser usada :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
modificador ( demo ): "(?s)(.*)<Foobar>"
(nas planilhas do Google =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)NOTAS SOBRE(?s)
:
Na maioria dos mecanismos que não sejam POSIX, o (?s)
modificador em linha (ou opção de sinalizador incorporado) pode ser usado para aplicar .
para corresponder a quebras de linha.
Se colocado no início do padrão, (?s)
altera o comportamento de todos .
no padrão. Se o (?s)
item for colocado em algum lugar após o início, apenas os .
afetados serão localizados à direita, a menos que esse seja um padrão passado para o Python re
. No Python re
, independentemente da (?s)
localização, todo o padrão .
é afetado. O (?s)
efeito é parado de usar (?-s)
. Um grupo modificado pode ser usado para afetar apenas um intervalo especificado de um padrão de regex (por exemplo Delim1(?s:.*?)\nDelim2.*
, fará a primeira .*?
correspondência entre as novas linhas e a segunda .*
corresponderá apenas ao restante da linha).
Nota POSIX :
Em mecanismos regex não POSIX, para corresponder a qualquer caractere, [\s\S]
/ [\d\D]
/ [\w\W]
construções podem ser usadas.
No POSIX, [\s\S]
não corresponde a nenhum caractere (como no JavaScript ou em qualquer mecanismo que não seja POSIX) porque as sequências de escape regex não são suportadas dentro das expressões de colchete. [\s\S]
é analisado como expressões de colchete que correspondem a um único caractere \
ou s
ou S
.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
para seus sinalizadores de expressão regular para refletir isso. E o árbitro é sempre os modificadores em linha. Onde (?-sm)(?s).*
redefine.
.
corresponde a qualquer caractere lá (incluindo quebras de linha). Veja esta demonstração online do Bash .
Go
na resposta!
Se você estiver usando a pesquisa Eclipse, poderá ativar a opção "DOTALL" para criar '.' corresponda a qualquer caractere, incluindo delimitadores de linha: basta adicionar "(? s)" no início da string de pesquisa. Exemplo:
(?s).*<FooBar>
(?s)
=>(?m)
Em muitos dialetos regex, /[\S\s]*<Foobar>/
fará exatamente o que você deseja. Fonte
([\s\S]*)<FooBar>
O ponto corresponde a todos, exceto às novas linhas (\ r \ n). Portanto, use \ s \ S, que corresponderá a TODOS os caracteres.
[text rangeOfString:regEx options:NSRegularExpressionSearch]
. Obrigado!
<FooBar>
Em Ruby rubivocê pode usar a m
opção ' ' (multilinha):
/YOUR_REGEXP/m
Veja a documentação do Regexp em ruby-doc.org para mais informações.
nós também podemos usar
(.*?\n)*?
para combinar com tudo, incluindo nova linha sem ganancioso
Isso tornará a nova linha opcional
(.*?|\n)*?
"."
normalmente não corresponde a quebras de linha. A maioria dos mecanismos de expressão regular permite adicionar o S
-flag (também chamado DOTALL
e SINGLELINE
) para fazer com que "."
também correspondam novas linhas. Se isso falhar, você pode fazer algo parecido [\S\s]
.
/(.*)<FooBar>/s
s faz com que Dot (.) corresponda aos retornos de carro
s
sinalizadores existem no PCRE, o mecanismo mais completo (disponível em Perl e PHP). O PCRE possui 10 sinalizadores (e muitos outros recursos) enquanto o JavaScript possui apenas 3 sinalizadores ( gmi
).
Na expressão regular baseada em java, você pode usar [\s\S]
s
sinalização ao padrão em Java, o JavaScript não possui a s
sinalização.
Observe que (.|\n)*
pode ser menos eficiente do que (por exemplo) [\s\S]*
(se as expressões regulares do seu idioma suportam essas fugas) e descobrir como especificar o modificador que faz. também correspondem a novas linhas. Ou você pode optar por alternativas como POSIXy [[:space:][:^space:]]*
.
Use o modificador de padrões sU obterá a correspondência desejada no PHP.
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-including-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php
No contexto do uso em idiomas, expressões regulares atuam em strings, não em linhas. Portanto, você deve poder usar a regex normalmente, assumindo que a sequência de entrada tenha várias linhas.
Nesse caso, o regex especificado corresponderá a toda a cadeia, pois "<FooBar>" está presente. Dependendo das especificidades da implementação do regex, o valor $ 1 (obtido de "(. *)") Será "fghij" ou "abcde \ nfghij". Como já foi dito, algumas implementações permitem controlar se o "." corresponderá à nova linha, dando a você a escolha.
O uso de expressões regulares com base em linhas é geralmente para coisas de linha de comando como egrep.
Eu tive o mesmo problema e resolvi-o provavelmente não da melhor maneira, mas funciona. Substituí todas as quebras de linha antes de fazer minha correspondência real:
mystring= Regex.Replace(mystring, "\r\n", "")
Estou manipulando o HTML para que as quebras de linha não sejam realmente importantes para mim neste caso.
Eu tentei todas as sugestões acima sem sorte, estou usando .Net 3.5 FYI
(\s|\S)
parece fazer o truque para mim!
(?s)
para fazer .
corresponder quaisquer caracteres. Não use (\s|\S)
isso para diminuir o desempenho.
Em Javascript, você pode usar [^] * para procurar por zero a infinitos caracteres, incluindo quebras de linha.
$("#find_and_replace").click(function() {
var text = $("#textarea").val();
search_term = new RegExp("[^]*<Foobar>", "gi");;
replace_term = "Replacement term";
var new_text = text.replace(search_term, replace_term);
$("#textarea").val(new_text);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij<Foobar></textarea>
geralmente. não corresponde a novas linhas, então tente((.|\n)*)<foobar>
\r
:.((?:.|\r?\n)*)<foobar>
Eu queria combinar um bloco particular se em java
...
...
if(isTrue){
doAction();
}
...
...
}
Se eu usar o regExp
if \(isTrue(.|\n)*}
incluía a chave de fechamento do bloco de método, então eu usei
if \(!isTrue([^}.]|\n)*}
para excluir a chave de fechamento da correspondência de curinga.
Freqüentemente, precisamos modificar uma substring com algumas palavras-chave espalhadas pelas linhas que precedem a substring. Considere um elemento xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
Suponha que desejemos modificar o 81, para algum outro valor, digamos 40. Primeiro identifique .UID.21..UID.
e depois pule todos os caracteres, incluindo \n
até .PercentCompleted.
. O padrão de expressão regular e a especificação de substituição são:
String hw = new String("<TASK>\n <UID>21</UID>\n <Name>Architectural design</Name>\n <PercentComplete>81</PercentComplete>\n</TASK>");
String pattern = new String ("(<UID>21</UID>)((.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
String replaceSpec = new String ("$1$2$440$6");
//note that the group (<PercentComplete>) is $4 and the group ((.|\n)*?) is $2.
String iw = hw.replaceFirst(pattern, replaceSpec);
System.out.println(iw);
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>40</PercentComplete>
</TASK>
O subgrupo (.|\n)
é provavelmente o grupo ausente $3
. Se fizermos a não captura até (?:.|\n)
então, o $3
é (<PercentComplete>)
. Portanto, o padrão e replaceSpec
também pode ser:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
e a substituição funciona corretamente como antes.
Normalmente, procurando três linhas consecutivas no Powershell, seria semelhante a:
$file = get-content file.txt -raw
$pattern = 'lineone\r\nlinetwo\r\nlinethree\r\n' # "windows" text
$pattern = 'lineone\nlinetwo\nlinethree\n' # "unix" text
$pattern = 'lineone\r?\nlinetwo\r?\nlinethree\r?\n' # both
$file -match $pattern
# output
True
Estranhamente, isso seria texto unix no prompt, mas o texto do Windows em um arquivo:
$pattern = 'lineone
linetwo
linethree
'
Aqui está uma maneira de imprimir as terminações de linha:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Uma maneira seria usar a s
bandeira (assim como a resposta aceita):
/(.*)<FooBar>/s
Uma segunda maneira seria usar o m
sinalizador (multilinha) e qualquer um dos seguintes padrões:
/([\s\S]*)<FooBar>/m
ou
/([\d\D]*)<FooBar>/m
ou
/([\w\W]*)<FooBar>/m
O jex.im visualiza expressões regulares: