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.
smodificador. Em vez disso, faça [^]*o mesmo efeito.
mmodificador
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');( tokenscontém um abcde\n fghijitem).
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 nopçã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=TRUEou 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"( -0coloca o arquivo inteiro na memória, -pimprime o arquivo após aplicar o script fornecido por -e). Observe que usar -000peirá 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, zhabilita 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, \Komite o texto correspondente até agora, *?é um quantificador lento, (?=<Foobar>)corresponde ao local antes <Foobar>.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file( Mativa o slurping de arquivo aqui). Nota pcregrepé uma boa solução para grepusuários de Mac OS .Mecanismos não baseados em POSIX :
smodificador PCRE_DOTALL : preg_match('~(.*)<Foobar>~s', $s, $m)( demo )RegexOptions.Singlelinesinalizador ( 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]smodificador (ou (?s)versão embutida no início) ( demo ):/(.*)<FooBar>/sre.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.DOTALLmodificador (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 MultiLinepropriedade do
RegExpobjeto é 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/ stringiregex 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>`)dotMatchesLineSeparatorsou (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 sou S.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_mpara 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 .
Gona 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 mopçã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 DOTALLe 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
ssinalizadores 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]
ssinalização ao padrão em Java, o JavaScript não possui a ssinalizaçã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 \naté .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 replaceSpectambé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 sbandeira (assim como a resposta aceita):
/(.*)<FooBar>/s
Uma segunda maneira seria usar o msinalizador (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: