Ad esempio, questa regex
(.*)<FooBar>
corrisponderà:
abcde<FooBar>
Ma come faccio ad abbinarlo su più righe?
abcde
fghij<FooBar>
Ad esempio, questa regex
(.*)<FooBar>
corrisponderà:
abcde<FooBar>
Ma come faccio ad abbinarlo su più righe?
abcde
fghij<FooBar>
Risposte:
Dipende dalla lingua, ma dovrebbe esserci un modificatore che puoi aggiungere al modello regex. In PHP è:
/(.*)<FooBar>/s
La s alla fine fa sì che il punto corrisponda a tutti i caratteri, comprese le nuove linee.
s
modificatore. Invece, fai [^]*
per lo stesso effetto.
m
modificatore
Prova questo:
((.|\n)*)<FooBar>
In pratica dice "qualsiasi personaggio o una nuova riga" ripetuto zero o più volte.
((.|\n|\r)*)<FooBar>
[\s\S]*
o (?s).*
.
La domanda è: può un .
modello adattarsi a qualsiasi personaggio? La risposta varia da motore a motore. La differenza principale è se il pattern viene utilizzato da una libreria regex POSIX o non POSIX.
Nota speciale su lua-patterns: non sono considerati espressioni regolari, ma .
corrispondono a qualsiasi carattere lì, come i motori basati su POSIX.
Un'altra nota su mATLAB e ottava: .
corrisponde a qualsiasi carattere predefinito ( demo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
( tokens
contiene un abcde\n fghij
oggetto).
Inoltre, in tutto IncrementoLe grammatiche regex del punto corrispondono alle interruzioni di riga per impostazione predefinita. La grammatica ECMAScript di Boost ti consente di disattivarlo con regex_constants::no_mod_m
( sorgente ).
Quanto a oracolo(è basato su POSIX), utilizzare l' n
opzione ( demo ):select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Motori basati su POSIX :
Un semplice .
abbina già le interruzioni di riga, non è necessario utilizzare alcun modificatore, vedibash( demo ).
Il TCL( demo ),PostgreSQL( demo ),r(TRE, motore predefinito di base R con no perl=TRUE
, per base R con perl=TRUE
o per schemi stringr / stringi , utilizzare il (?s)
modificatore inline) ( demo ) anche trattare .
allo stesso modo.
Tuttavia , la maggior parte degli strumenti basati su POSIX elabora l'input riga per riga. Quindi, .
non corrisponde alle interruzioni di riga solo perché non rientrano nell'ambito. Ecco alcuni esempi su come sovrascrivere questo:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
( H;1h;$!d;x;
assorbe il file in memoria). Se devono essere incluse intere righe, sed '/start_pattern/,/end_pattern/d' file
(la rimozione dall'inizio termina con le righe corrispondenti incluse) o sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(con le righe corrispondenti escluse) può essere preso in considerazione.perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
( -0
assorbe l'intero file in memoria, -p
stampa il file dopo aver applicato lo script fornito da -e
). Si noti che l'utilizzo -000pe
ridurrà il file e attiverà la "modalità paragrafo" in cui Perl utilizza newline consecutive ( \n\n
) come separatore dei record.grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Qui, z
abilita (?s)
lo slurping dei file, abilita la modalità DOTALL per il .
modello, (?i)
abilita la modalità senza distinzione tra maiuscole e minuscole, \K
omette il testo corrispondente finora, *?
è un quantificatore pigro, (?=<Foobar>)
corrisponde alla posizione precedente <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
( M
abilita lo slurping dei file qui). Nota pcregrep
è una buona soluzione per gli grep
utenti di Mac OS .Motori non basati su POSIX :
s
modificatore modificatore PCRE_DOTALL : preg_match('~(.*)<Foobar>~s', $s, $m)
( demo )RegexOptions.Singleline
flag ( demo ): var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
l'opzione in linea:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
modificatore (o la (?s)
versione incorporata all'inizio) ( demo ):/(.*)<FooBar>/s
re.DOTALL
(o re.S
) flag o (?s)
modificatore inline ( demo ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(e poi if m:
, print(m.group(1))
)Pattern.DOTALL
modificatore (o (?s)
flag incorporato ) ( demo ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
modificatore in-pattern ( demo ):regex = /(?s)(.*)<FooBar>/
(?s)
modificatore ( demo ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
o soluzioni alternative [\d\D]
/ [\w\W]
/ [\s\S]
( demo ):s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Utilizzare [\s\S]
o le soluzioni alternative JS ( demo ):regex rex(R"(([\s\S]*)<FooBar>)");
VBA vbscript- Utilizzare lo stesso approccio in JavaScript, ([\s\S]*)<Foobar>
. ( NOTA : a volte si ritiene erroneamente che la MultiLine
proprietà
RegExp
dell'oggetto sia l'opzione per consentire la .
corrispondenza tra le interruzioni di riga, mentre, in realtà, cambia solo il comportamento ^
e $
per far coincidere l'inizio / la fine delle righe anziché le stringhe , come in JS regex ) comportamento.)
rubino- Usa il modificatore /m
MULTILINE ( demo ):s[/(.*)<Foobar>/m, 1]
(?s)
: regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
( demo )stringr
/ stringi
regex che sono alimentate con il motore regex ICU, usano anche (?s)
: stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
( demo )(?s)
all'avvio ( demo ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
o (più semplice) passare il (?s)
modificatore in linea al modello:let rx = "(?s)(.*)<Foobar>"
(?s)
funziona nel modo più semplice, ma ecco come può essere utilizzata l' opzione :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
modificatore ( demo ): "(?s)(.*)<Foobar>"
(in Google Spreadsheets, =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)NOTE SU(?s)
:
Nella maggior parte dei motori non POSIX, è (?s)
possibile utilizzare il modificatore inline (o l'opzione flag incorporata) per applicare le .
interruzioni di riga.
Se posizionato all'inizio del modello, (?s)
cambia il comportamento di tutti .
nel modello. Se (?s)
viene posizionato da qualche parte dopo l'inizio, .
saranno interessati solo quelli che si trovano alla sua destra a meno che questo non sia uno schema passato a Python re
. In Python re
, indipendentemente dalla (?s)
posizione, l'intero modello .
è interessato. L' (?s)
effetto viene interrotto usando (?-s)
. Un gruppo modificato può essere utilizzato per influenzare solo un intervallo specificato di un modello regex (ad es. Delim1(?s:.*?)\nDelim2.*
Farà la prima .*?
corrispondenza tra le nuove linee e la seconda .*
corrisponderà solo al resto della linea).
Nota POSIX :
Nei motori regex non POSIX, per abbinare qualsiasi carattere, [\s\S]
/ [\d\D]
/ [\w\W]
costrutti possono essere utilizzati.
In POSIX, [\s\S]
non corrisponde alcun carattere (come in JavaScript o qualsiasi motore non POSIX) perché le sequenze di escape regex non sono supportate all'interno delle espressioni parentesi. [\s\S]
viene analizzato come espressioni di parentesi che corrispondono a un singolo carattere \
o s
oppure S
.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
per i loro flag di regex per riflettere ciò. E l'arbitor è sempre i modificatori in linea. Dove si (?-sm)(?s).*
ripristina.
.
corrisponde a qualsiasi carattere lì (comprese le interruzioni di riga). Guarda questa demo online di Bash .
Go
nella risposta!
Se stai usando la ricerca Eclipse, puoi abilitare l'opzione "DOTALL" per creare '.' corrisponde a qualsiasi carattere inclusi i delimitatori di riga: aggiungi "(? s)" all'inizio della stringa di ricerca. Esempio:
(?s).*<FooBar>
(?s)
=>(?m)
In molti dialetti regex, /[\S\s]*<Foobar>/
farà esattamente quello che vuoi. fonte
([\s\S]*)<FooBar>
Il punto corrisponde a tutti tranne alle nuove righe (\ r \ n). Quindi usa \ s \ S, che corrisponderà a TUTTI i caratteri.
[text rangeOfString:regEx options:NSRegularExpressionSearch]
. Grazie!
<FooBar>
In rubino rubinopuoi usare l' m
opzione ' ' (multilinea):
/YOUR_REGEXP/m
Vedere la documentazione di Regexp su ruby-doc.org per ulteriori informazioni.
possiamo anche usare
(.*?\n)*?
per abbinare tutto compreso newline senza avidità
Ciò renderà la nuova linea opzionale
(.*?|\n)*?
"."
normalmente non corrisponde alle interruzioni di riga. La maggior parte dei motori regex ti consente di aggiungere il S
-flag (chiamato anche DOTALL
e SINGLELINE
) per far "."
corrispondere anche i newline. Se fallisce, potresti fare qualcosa del genere [\S\s]
.
/(.*)<FooBar>/s
la s fa sì che Dot (.) corrisponda ai ritorni a capo
s
flag esistono in PCRE, il motore più completo (disponibile in Perl e PHP). PCRE ha 10 flag (e molte altre funzionalità) mentre JavaScript ha solo 3 flag ( gmi
).
Nell'espressione regolare basata su Java puoi usare [\s\S]
s
flag al modello in Java e JavaScript non ha il s
flag.
Usa modificatore di pattern sU otterrà la corrispondenza desiderata in 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
Nel contesto dell'uso all'interno delle lingue, le espressioni regolari agiscono sulle stringhe, non sulle linee. Quindi dovresti essere in grado di usare normalmente il regex, supponendo che la stringa di input abbia più righe.
In questo caso, la regex fornita corrisponderà all'intera stringa, poiché è presente "<FooBar>". A seconda delle specifiche dell'implementazione di regex, il valore $ 1 (ottenuto da "(. *)") Sarà "fghij" o "abcde \ nfghij". Come altri hanno già detto, alcune implementazioni consentono di controllare se il "." corrisponderà alla nuova riga, dandoti la scelta.
L'uso di espressioni regolari basate su linea è in genere per cose da riga di comando come egrep.
Ho avuto lo stesso problema e risolto probabilmente non nel modo migliore ma funziona. Ho sostituito tutte le interruzioni di riga prima di fare la mia vera partita:
mystring= Regex.Replace(mystring, "\r\n", "")
Sto manipolando HTML, quindi in questo caso le interruzioni di riga non contano davvero per me.
Ho provato tutti i suggerimenti di cui sopra senza fortuna, sto usando .Net 3.5 FYI
(\s|\S)
sembra fare il trucco per me!
(?s)
per far .
corrispondere qualsiasi carattere. Non utilizzare (\s|\S)
ciò rallenterà le prestazioni.
In Javascript puoi usare [^] * per cercare da zero a infiniti caratteri, comprese le interruzioni di riga.
$("#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>
generalmente . non corrisponde a newline, quindi prova((.|\n)*)<foobar>
\r
.:((?:.|\r?\n)*)<foobar>
Volevo abbinare un blocco if particolare in Java
...
...
if(isTrue){
doAction();
}
...
...
}
Se uso regExp
if \(isTrue(.|\n)*}
includeva la parentesi graffa di chiusura per il blocco del metodo, quindi l'ho usato
if \(!isTrue([^}.]|\n)*}
per escludere la parentesi graffa di chiusura dalla corrispondenza dei caratteri jolly.
Spesso dobbiamo modificare una sottostringa con alcune parole chiave sparse tra le righe che precedono la sottostringa. Considera un elemento xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
Supponiamo di voler modificare 81, ad un altro valore, diciamo 40. Prima identifica .UID.21..UID.
, quindi salta tutti i caratteri incluso \n
till .PercentCompleted.
. Il modello di espressione regolare e la specifica di sostituzione sono:
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>
Il sottogruppo (.|\n)
è probabilmente il gruppo mancante $3
. Se lo rendiamo non-cattura (?:.|\n)
allora $3
è (<PercentComplete>)
. Quindi il modello e replaceSpec
può anche essere:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
e la sostituzione funziona correttamente come prima.
In genere la ricerca di tre righe consecutive in Powershell sarebbe simile 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
Stranamente, questo sarebbe unix text al prompt, ma il testo di Windows in un file:
$pattern = 'lineone
linetwo
linethree
'
Ecco un modo per stampare le terminazioni di riga:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Un modo sarebbe usare la s
bandiera (proprio come la risposta accettata):
/(.*)<FooBar>/s
Un secondo modo sarebbe quello di usare la m
bandiera (multilinea) e uno dei seguenti modelli:
/([\s\S]*)<FooBar>/m
o
/([\d\D]*)<FooBar>/m
o
/([\w\W]*)<FooBar>/m
jex.im visualizza le espressioni regolari: