Par exemple, cette expression rationnelle
(.*)<FooBar>
correspondra à:
abcde<FooBar>
Mais comment puis-je le faire correspondre sur plusieurs lignes?
abcde
fghij<FooBar>
Cela dépend de la langue, mais il devrait y avoir un modificateur que vous pouvez ajouter au motif regex. En PHP c'est:
/(.*)<FooBar>/s
Le signe s à la fin fait que le point correspond à tous les caractères , y compris les retours à la ligne.
Essaye ça:
((.|\n)*)<FooBar>
Il dit essentiellement "n'importe quel caractère ou nouvelle ligne" répété zéro fois ou plus.
Si vous utilisez la recherche Eclipse, vous pouvez activer l'option "DOTALL" pour que "." correspond à n'importe quel caractère, y compris les délimiteurs de ligne: ajoutez simplement "(? s)" au début de votre chaîne de recherche. Exemple:
(?s).*<FooBar>
La question est la suivante: le modèle .
peut-il correspondre any caractère? La réponse varie d'un moteur à l'autre. La principale différence est de savoir si le motif est utilisé par une bibliothèque regex POSIX ou non-POSIX.
Remarque spéciale sur lua-patterns : elles ne sont pas considérées comme des expressions régulières, mais .
correspond à tous les caractères présents, de la même manière que les moteurs basés sur POSIX.
Une autre note sur matlab et octave : le .
correspond à tout caractère par défaut ( démo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
(tokens
contient un élément abcde\n fghij
).
De plus, dans toutes les grammaires regex de boost , le point correspond aux sauts de ligne par défaut. La grammaire ECMAScript de Boost vous permet de désactiver cette option avec regex_constants::no_mod_m
( source ).
Comme pour Oracle (basé sur POSIX), utilisez option n
( démo ): select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
moteurs basés sur POSIX:
Un simple .
correspond déjà à des sauts de ligne, vous n'avez pas besoin d'utiliser de modificateur, voir bash ( démo ).
Les tcl ( démo ), postgresql ( démo ), r (TRE, moteur par défaut de base R sans Perl=TRUE
, pour la base R avec Perl=TRUE
ou pour stringr / stringi modèles, utilisez le modificateur inline (?s)
) ( démo ) traite également .
de la même manière.
Cependant , la plupart des outils POSIX traitent les entrées ligne par ligne. Par conséquent, .
ne correspond pas aux sauts de ligne simplement parce qu'ils ne sont pas dans la portée. Voici quelques exemples comment remplacer ceci:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
(H;1h;$!d;x;
insère le fichier en mémoire). Si des lignes entières doivent être incluses, sed '/start_pattern/,/end_pattern/d' file
(supprimer du début se terminera par les lignes correspondantes incluses) ou sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(avec les lignes correspondantes exclues) peut être pris en compte.Perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
(-0
insère tout le fichier dans la mémoire, -p
imprime le fichier après application du script donné par -e
). Notez que l'utilisation de -000pe
réduira le fichier et activera le 'mode paragraphe' où Perl utilise des sauts de ligne consécutifs (\n\n
) comme séparateur d'enregistrement.grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Ici, z
permet de lisser le fichier, (?s)
active le mode DOTALL pour le modèle .
, (?i)
active le mode sans distinction de casse, \K
omet le texte correspondant jusqu'ici, *?
est un quantificateur lazy, (?=<Foobar>)
correspond à l'emplacement précédent <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
(M
permet le slurping de fichier ici). Remarque pcregrep
est une bonne solution pour les utilisateurs de Mac OS grep
.moteurs non basés sur POSIX:
s
modificateur PCRE_DOTALL : preg_match('~(.*)<Foobar>~s', $s, $m)
( démo )RegexOptions.Singleline
flag ( démo ):var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
option en ligne: $s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
(ou la version (?s)
au début) ( démo ): /(.*)<FooBar>/s
re.DOTALL
(ou re.S
) ou le modificateur inline (?s)
( démo ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(puis if m:
, print(m.group(1))
)Pattern.DOTALL
(ou l'indicateur en ligne (?s)
) ( démo ): Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
modificateur intégré au motif ( démo ): regex = /(?s)(.*)<FooBar>/
(?s)
( démo ): "(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
ou des solutions de contournement [\d\D]
/[\w\W]
/[\s\S]
( démo ): s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Utilisez [\s\S]
ou les solutions de contournement JS ( démo ): regex rex(R"(([\s\S]*)<FooBar>)");
([\s\S]*)<Foobar>
./m
MULTILIGNE modificateur ( démo ): s[/(.*)<Foobar>/m, 1]
(?s)
au début ( démo ): re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
ou (plus facilement) passez le modificateur inline (?s)
au motif: let rx = "(?s)(.*)<Foobar>"
(?s)
fonctionne le plus facilement, mais voici comment l'option peut être utilisée : NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
( démo ): "(?s)(.*)<Foobar>"
(dans Google Spreadsheets, =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)NOTES ON (?s)
:
Dans la plupart des moteurs non POSIX, le modificateur inline (?s)
(ou l'option d'indicateur intégré) peut être utilisé pour appliquer .
afin de faire correspondre les sauts de ligne.
S'il est placé au début du modèle, (?s)
modifie le comportement de tous les .
du modèle. Si le (?s)
est placé quelque part après le début, seuls les .
situés à sa droite seront affectés sauf il s'agit d'un modèle passé à Python re
. Dans Python re
, quel que soit l'emplacement (?s)
, l'ensemble du motif .
est affecté. L'effet (?s)
est arrêté à l'aide de (?-s)
. Un groupe modifié peut être utilisé pour n’affecter qu’une plage spécifiée d’un motif regex (par exemple, Delim1(?s:.*?)\nDelim2.*
fera correspondre le premier .*?
aux nouvelles lignes et le second .*
ne correspondra qu’au reste de la ligne).
note POSIX:
Dans les moteurs autres que les expressions rationnelles, les constructions [\s\S]
/[\d\D]
/[\w\W]
peuvent correspondre à n'importe quel caractère.
Dans POSIX, [\s\S]
ne correspond à aucun caractère (comme dans JavaScript ou dans un moteur autre que POSIX) car les séquences d'échappement des expressions rationnelles ne sont pas prises en charge dans les expressions entre crochets. [\s\S]
est analysé comme des expressions entre crochets qui correspondent à un seul caractère, \
ou s
ou S
.
En JavaScript, utilisez /[\S\s]*<Foobar>/
. Source
([\s\S]*)<FooBar>
Le point correspond à tous sauf aux nouvelles lignes (\ r\n). Utilisez donc\s\S, qui correspondra à TOUS les caractères.
Dans Ruby Ruby vous pouvez utiliser le paramètre 'm
'option (multiligne):
/YOUR_REGEXP/m
Voir la documentation Regexp sur Ruby-doc.org pour plus d'informations.
on peut aussi utiliser
(.*?\n)*?
pour correspondre à tout, y compris newline sans gourmand
Cela rendra la nouvelle ligne facultative
(.*?|\n)*?
"."
ne correspond normalement pas aux sauts de ligne. La plupart des moteurs de regex vous permettent d'ajouter l'indicateur S
- (également appelé DOTALL
et SINGLELINE
) pour que "."
corresponde également aux nouvelles lignes. Si cela échoue, vous pouvez faire quelque chose comme [\S\s]
.
Pour Eclipse travaillé expression suivante:
Foo
jadajada Bar "
Expression régulière:
Foo[\S\s]{1,10}.*Bar*
/(.*)<FooBar>/s
s fait que Dot (.) correspond aux retours chariot
Dans l'expression régulière basée sur Java, vous pouvez utiliser [\s\S]
Utilisez RegexOptions.Singleline, cela change le sens de. inclure les nouvelles lignes
Regex.Replace (content, searchText, replaceText, RegexOptions.Singleline);
Notez que (.|\n)*
peut être moins efficace que (par exemple) [\s\S]*
(si les expressions rationnelles de votre langue prennent en charge de tels échappements) et que de trouver comment spécifier le modificateur qui le rend. correspondent également aux nouvelles lignes. Ou vous pouvez utiliser des alternatives POSIXy comme [[:space:][:^space:]]*
.
Utilisez le modificateur de modèle sU pour obtenir la correspondance souhaitée en PHP.
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-including-new-linehttp://php.net/manual/en/reference.pcre. pattern.modifiers.php
J'ai eu le même problème et résolu dans probablement pas la meilleure façon, mais cela fonctionne. J'ai remplacé tous les sauts de ligne avant mon vrai match:
mystring= Regex.Replace(mystring, "\r\n", "")
Je manipule du HTML afin que les sauts de ligne ne m'importent pas vraiment dans ce cas.
J'ai essayé toutes les suggestions ci-dessus sans succès, j'utilise .Net 3.5 FYI
En Javascript, vous pouvez utiliser [^] * pour rechercher des caractères de zéro à infini, y compris les sauts de ligne.
$("#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>
Dans le contexte de l'utilisation dans les langues, les expressions régulières agissent sur des chaînes, pas des lignes. Vous devriez donc pouvoir utiliser l'expression régulière normalement, en supposant que la chaîne d'entrée comporte plusieurs lignes.
Dans ce cas, l'expression rationnelle donnée correspondra à la chaîne entière, car "<FooBar>" est présent. Selon les spécificités de l'implémentation de regex, la valeur $ 1 (obtenue à partir de "(. *)") Sera "fghij" ou "abcde\nfghij". Comme d'autres l'ont dit, certaines implémentations vous permettent de contrôler si le "." correspondra à la nouvelle ligne, vous donnant le choix.
L'utilisation d'une expression régulière basée sur une ligne est généralement utilisée pour des opérations en ligne de commande telles que egrep.
La recherche de trois lignes consécutives dans Powershell ressemble à ceci:
$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
Bizarrement, ce serait un texte unix à l’invite, mais un texte Windows dans un fichier:
$pattern = 'lineone
linetwo
linethree
'
Voici un moyen d'imprimer les fins de ligne:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Nous devons souvent modifier une sous-chaîne avec quelques mots-clés répartis sur les lignes précédant la sous-chaîne. Considérons un élément xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
Supposons que nous voulions modifier le 81, en lui attribuant une autre valeur, disons 40. Identifiez d'abord .UID.21..UID.
, puis ignorez tous les caractères, y compris \n
jusqu'à .PercentCompleted.
. Le modèle d'expression régulière et la spécification de remplacement sont les suivants:
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>
Le sous-groupe (.|\n)
est probablement le groupe manquant $3
. Si nous le faisons sans capture par (?:.|\n)
alors le $3
est (<PercentComplete>)
. Donc, le motif et replaceSpec
peuvent aussi être:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
et le remplacement fonctionne correctement comme avant.
Je voulais faire correspondre un bloc si particulier en Java
...
...
if(isTrue){
doAction();
}
...
...
}
Si j'utilise le regExp
if \(isTrue(.|\n)*}
il comprenait l'accolade de fermeture pour le bloc de méthode alors j'ai utilisé
if \(!isTrue([^}.]|\n)*}
pour exclure l'accolade de fermeture de la correspondance avec le caractère générique.
généralement . ne correspond pas aux nouvelles lignes, alors essayez ((.|\n)*)<foobar>