Comment faire correspondre un caractère sur plusieurs lignes dans une expression régulière?

Par exemple, cette regex

(.*) 

correspondra à:

 abcde 

Mais comment puis-je le faire correspondre sur plusieurs lignes?

 abcde fghij 

Cela dépend de la langue, mais il doit y avoir un modificateur que vous pouvez append au modèle de regex. En PHP c’est:

 /(.*)/s 

Le s à la fin fait correspondre le point à tous les caractères, y compris les nouvelles lignes.

Essaye ça:

 ((.|\n)*) 

Il dit en gros “tout caractère ou nouvelle ligne” répété zéro ou plus.

Si vous utilisez la recherche Eclipse, vous pouvez activer l’option “DOTALL” pour faire “.” 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).* 

Dans JavaScript, utilisez /[\S\s]*/ . La source

La question est, peut . motif correspond à n’importe quel personnage? La réponse varie d’un moteur à l’autre. La principale différence est de savoir si le modèle est utilisé par une bibliothèque de regex POSIX ou non-POSIX.

Note spéciale à propos des lua-patterns : ils ne sont pas considérés comme des expressions régulières, mais . correspond à n’importe quel caractère, comme 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"; expression = '(.*)*'; [tokens,matches] = regexp(str,expression,'tokens','match'); str = "abcde\n fghij"; expression = '(.*)*'; [tokens,matches] = regexp(str,expression,'tokens','match'); (les tokens contiennent un élément abcde\n fghij ).

De plus, dans toutes les grammaires de regex de boost , le point correspond aux sauts de ligne par défaut. La grammaire ECMAScript de Boost vous permet de désactiver cette regex_constants::no_mod_m avec regex_constants::no_mod_m ( source ).

Quant à oracle (il est basé sur POSIX), utilisez l’ option n ( demo ): select regexp_substr('abcde' || chr(10) ||' fghij', '(.*)', 1, 1, 'n', 1) as results from dual

Moteurs basés sur POSIX :

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 les patterns ssortingngr / ssortingngi , utilisez le (?s) in (?s) modificateur inline) ( démo ) . Un simple correspond déjà aux sauts de ligne, pas besoin d’utiliser de modificateurs.

Moteurs non basés sur POSIX :

  • php – Utilise s modificateur PCRE_DOTALL modificateur : preg_match('~(.*)~s', $s, $m) ( démo )
  • c # – Utilisez l’indicateur RegexOptions.Singleline ( démo ):
    var result = Regex.Match(s, @"(.*)", RegexOptions.Singleline).Groups[1].Value;
    var result = Regex.Match(s, @"(?s)(.*)").Groups[1].Value;
  • powershell – Utilisez l’option en ligne (?s) : $s = "abcde`nfghij"; $s -match "(?s)(.*)"; $matches[1] $s = "abcde`nfghij"; $s -match "(?s)(.*)"; $matches[1]
  • perl – Utilise s modificateur (ou (?s) version en ligne au début) ( démo ): /(.*)/s
  • python – Utilisez les re.DOTALL (ou re.S ) ou le modificateur inline (?s) ( démo ): m = re.search(r"(.*)", s, flags=re.S) ( et ensuite if m: print(m.group(1)) )
  • java – Utilisez le modificateur Pattern.DOTALL (ou l’ Pattern.DOTALL inline (?s) ) ( démo ): Pattern.comstack("(.*)", Pattern.DOTALL)
  • groovy – Utilise le modificateur in-pattern ( démo ): regex = /(?s)(.*)/
  • scala – Utilise le modificateur ( démo ): "(?s)(.*)".r.findAllIn("abcde\n fghij").matchData foreach { m => println(m.group(1)) }
  • javascript – Utilise [^] ou des solutions de contournement [\d\D] / [\w\W] / [\s\S] ( démo ): s.match(/([\s\S]*)/)[1]
  • c ++ ( std::regex ) Utilisez [\s\S] ou les solutions de contournement JS ( démo ): regex rex(R"(([\s\S]*))");
  • vba – Utilisez la même approche que dans JavaScript, ([\s\S]*) .
  • ruby – Utilisez /m modificateur MULTILINE ( démo ): s[/(.*)/m, 1]
  • go – Utilise le modificateur inline (?s) au début ( démo ): re: = regexp.MustComstack(`(?s)(.*)`)
  • swift – Utilisez dotMatchesLineSeparators ou (plus facile) passez le modificateur inline (?s) au pattern: let rx = "(?s)(.*)"
  • objective-c – Identique à Swift, (?s) fonctionne le plus NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:&regexError]; , mais voici comment utiliser cette option : NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:&regexError];
  • re2 , google-apps-script – Utilise le modificateur ( démo ): "(?s)(.*)" (dans Google Spreadsheets, =REGEXEXTRACT(A2,"(?s)(.*)") )

NOTES ON (?s) :

Dans la plupart des moteurs non-POSIX, le modificateur inline (?s) (ou l’option d’indicateur incorporé) peut être utilisé pour appliquer . pour correspondre aux sauts de ligne.

S’il est placé au début du motif, (?s) modifie le comportement de tous . dans le motif. Si le (?s) Est placé quelque part après le début, seulement ceux-là . seront affectés à la droite de celui-ci, sauf s’il s’agit d’un modèle transmis à Python re . En Python re , quel que soit l’emplacement (?s) , l’ensemble du motif . sont affectés. L’effet (?s) est arrêté en utilisant (?-s) . Un groupe modifié peut être utilisé pour affecter uniquement une plage spécifiée d’un motif d’ Delim1(?s:.*?)\nDelim2.* (par exemple, Delim1(?s:.*?)\nDelim2.* la première correspondance .*? Delim1(?s:.*?)\nDelim2.* nouvelles lignes et la seconde rest de la ligne).

Note POSIX :

Dans les moteurs sans regex, pour correspondre à n’importe quel caractère, les constructions [\s\S] / [\d\D] / [\w\W] peuvent être utilisées.

Dans POSIX, [\s\S] ne correspond à aucun caractère (comme dans JavaScript ou tout autre moteur non POSIX) car les séquences d’échappement regex ne sont pas sockets en charge dans les expressions entre parenthèses. [\s\S] est analysé comme une expression de parenthèse correspondant à un seul caractère, \ ou s ou S

([\s\S]*)

Le point correspond à tous sauf newlines (\ r \ n). Utilisez donc \ s \ S, qui correspondra à TOUS les caractères.

Dans Ruby Ruby, vous pouvez utiliser l’option ‘ m ‘ (multiline):

 /YOUR_REGEXP/m 

Voir la documentation Regexp sur ruby-doc.org pour plus d’informations.

"." ne correspond normalement pas aux sauts de ligne. La plupart des moteurs de regex vous permettent d’append le S -flag (également appelé DOTALL et SINGLELINE ) pour faire "." correspondent également à des nouvelles lignes. Si cela échoue, vous pourriez faire quelque chose comme [\S\s] .

Pour Eclipse a travaillé l’expression suivante:

Foo

jadajada Bar ”

Expression régulière:

 Foo[\S\s]{1,10}.*Bar* 
 /(.*)/s 

le s provoque le point (.) pour correspondre aux retours chariot

on peut aussi utiliser

 (.*?\n)*? 

pour faire correspondre tout, y compris newline sans gourmandise

Cela rendra la nouvelle ligne facultative

 (.*?|\n)*? 

Notez que (.|\n)* peut être moins efficace que (par exemple) [\s\S]* (si les expressions rationnelles de votre langue prennent en charge de telles échappées) et que vous cherchiez à spécifier le modificateur qui le fait. correspondent également à des nouvelles lignes. Ou vous pouvez aller avec des alternatives POSIXy comme [[:space:][:^space:]]* .

Utilisez RegexOptions.Singleline, cela change la signification de. inclure les nouvelles lignes

Regex.Replace (contenu, searchText, replaceText, RegexOptions.Singleline);

Solution:

Utilisez le modificateur de pattern sU pour obtenir la correspondance souhaitée en PHP.

Exemple:

 preg_match('/(.*)/sU',$content,$match); 

La source:

http://dreamluverz.com/developers-tools/regex-match-all-including-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php

Dans les expressions régulières basées sur Java, vous pouvez utiliser [\s\S]

Dans le contexte de l’utilisation dans les langages, les expressions régulières agissent sur les chaînes, pas les lignes. Vous devriez donc pouvoir utiliser le regex normalement, en supposant que la chaîne d’entrée comporte plusieurs lignes.

Dans ce cas, l’expression régulière donnée correspondra à la chaîne entière, car “” est présent. Selon les spécificités de l’implémentation regex, la valeur $ 1 (obtenue à partir du “(. *)”) Sera soit “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.

Les expressions rationnelles basées sur les lignes sont généralement utilisées pour les lignes de commande comme egrep.

J’ai eu le même problème et je l’ai résolu probablement pas le meilleur, mais ça marche. J’ai remplacé tous les sauts de ligne avant de faire mon vrai match:

 myssortingng= Regex.Replace(myssortingng, "\r\n", "") 

Je manipule le HTML donc les sauts de ligne n’ont pas vraiment d’importance dans ce cas.

J’ai essayé toutes les suggestions ci-dessus sans succès, j’utilise .Net 3.5 FYI

Je voulais faire correspondre un bloc si particulier en Java

  ... ... if(isTrue){ doAction(); } ... ... } 

Si j’utilise le regExp

 if \(isTrue(.|\n)*} 

il a inclus l’accolade de fermeture pour le bloc de méthode, donc j’ai utilisé

 if \(!isTrue([^}.]|\n)*} 

pour exclure l’accolade de fermeture de la correspondance générique.

Souvent, nous devons modifier une sous-chaîne avec quelques mots-clés répartis entre les lignes précédant la sous-chaîne. Considérons un élément xml:

  21 Architectural design 81  

Supposons que nous voulions modifier le 81, à une autre valeur, disons 40. Commencez par identifier .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:

 Ssortingng hw = new Ssortingng("\n 21\n Architectural design\n 81\n"); Ssortingng pattern = new Ssortingng ("(21)((.|\n)*?)()(\\d+)()"); Ssortingng replaceSpec = new Ssortingng ("$1$2$440$6"); //note that the group () is $4 and the group ((.|\n)*?) is $2. Ssortingng iw = hw.replaceFirst(pattern, replaceSpec); System.out.println(iw);  21 Architectural design 40  

Le sous-groupe (.|\n) est probablement le groupe manquant $3 . Si nous le rendons non capturant par (?:.|\n) alors le $3 est () . Ainsi, le pattern et replaceSpec peuvent également être:

 pattern = new Ssortingng("(21)((?:.|\n)*?)()(\\d+)()"); replaceSpec = new Ssortingng("$1$2$340$5") 

et le remplacement fonctionne correctement comme avant.

généralement . ne correspond pas aux nouvelles lignes, alors essayez ((.|\n)*)