J'ai trouvé des articles très similaires, mais je n'arrive pas à comprendre mon expression régulière ici.
J'essaie d'écrire une expression régulière qui renvoie une chaîne située entre deux autres chaînes. Par exemple: je veux obtenir la chaîne qui réside entre les chaînes "vache" et "lait".
Ma vache donne toujours du lait
retournerais
"donne toujours"
Voici l'expression que j'ai reconstituée jusqu'à présent:
(?=cow).*(?=milk)
Cependant, cela retourne la chaîne "vache donne toujours".
Un lookahead (cette partie (?=
) ne consomme aucune entrée. C'est un assertion de largeur nulle (comme le sont les vérifications de limites et les recherches).
Vous voulez une correspondance régulière ici, pour consommer la portion cow
. Pour capturer la partie intermédiaire, vous utilisez un groupe de capture (placez simplement la partie du motif que vous souhaitez capturer entre parenthèses):
cow(.*)milk
Aucun coup d'oeil n'est nécessaire du tout.
Expression régulière pour obtenir une chaîne entre deux chaînes en JavaScript
La solution la plus complète qui fonctionne dans la plupart des cas consiste à utiliser un groupe de capture avec un correspondance de points paresseux. motif . Cependant, un point .
dans une expression rationnelle JavaScript ne correspond pas aux caractères de saut de ligne. Ainsi, dans 100% des cas, un [^]
ou [\s\S]
/[\d\D]
/[\w\W]
construit.
Dans les environnements JavaScript prenant en charge ECMAScript 2018 , le modificateur s
permet à .
de faire correspondre tout caractère, y compris les caractères de fin de ligne, et le moteur des expressions régulières prend en charge les contours de longueur variable. Donc, vous pouvez utiliser une regex comme
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
Dans les deux cas, la position actuelle est vérifiée pour cow
avec tout espacement égal ou supérieur à 1/0 après cow
, puis tous les caractères 0+ aussi peu que possible sont appariés et consommés (= ajouté à la valeur de correspondance ), puis milk
est vérifié (avec tout espacement 1/0 ou plus avant cette sous-chaîne).
Ce scénario et tous les autres scénarios ci-dessous sont pris en charge par tous les environnements JavaScript. Voir les exemples d'utilisation au bas de la réponse.
cow (.*?) milk
cow
est trouvé en premier, puis un espace, puis tous les caractères 0+ autres que les caractères de fin de ligne, aussi peu que possible, car *?
est un quantificateur paresseux, sont capturés dans le groupe 1, puis dans un espace avec milk
doit suivre (et ceux-ci sont appariés et consommés aussi).
cow ([\s\S]*?) milk
Ici, cow
et un espace sont mis en correspondance en premier, puis tous les caractères 0+ aussi peu que possible sont mis en correspondance et capturés dans le groupe 1, puis un espace avec milk
en correspondance.
Si vous avez une chaîne du type >>>15 text>>>67 text2>>>
et qu'il vous faut 2 correspondances entre >>>
+ number
+ whitespace
et >>>
, vous ne pouvez pas utiliser />>>\d+\s(.*?)>>>/g
car cela ne trouvera qu'une correspondance car le >>>
avant 67
est déjà consommé lors de la recherche du premier rencontre. Vous pouvez utiliser un lookahead positif pour vérifier la présence du texte sans réellement le "gober" (c'est-à-dire l'ajouter à la correspondance). :
/>>>\d+\s(.*?)(?=>>>)/g
Voir le démonstration en ligne regex donnant text1
et text2
en tant que contenu du groupe 1 trouvé.
Voir aussi Comment obtenir toutes les correspondances possibles pour une chaîne .
Un modèle de correspondance de points paresseux (.*?
) dans les modèles regex peut ralentir l'exécution du script si une très longue entrée est donnée. Dans de nombreux cas, la technique de dérouler la boucle est plus utile. En essayant de tout saisir entre cow
et milk
à partir de "Their\ncow\ngives\nmore\nmilk"
, nous voyons qu'il faut juste faire correspondre toutes les lignes qui ne commencent pas par milk
, donc au lieu de - cow\n([\s\S]*?)\nmilk
on peut utiliser:
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
Voir le démo regex (s'il peut y avoir \r\n
, utilisez /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). Avec cette petite chaîne de test, le gain de performance est négligeable, mais avec un texte très volumineux, vous sentirez la différence (surtout si les lignes sont longues et que les sauts de ligne ne sont pas très nombreux).
Exemple d'utilisation de regex en JavaScript:
//Single/First match expected: use no global modifier and access match[1] console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]); // Multiple matches: get multiple matches with a global modifier and // trim the results if length of leading/trailing delimiters is known var s = "My cow always gives milk, thier cow also gives milk"; console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);})); //or use RegExp#exec inside a loop to collect all the Group 1 contents var result = [], m, rx = /cow (.*?) milk/g; while ((m=rx.exec(s)) !== null) { result.Push(m[1]); } console.log(result);
Voici une regex qui saisira le lien entre vache et lait (sans espace de début/fin):
srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");
Un exemple: http://jsfiddle.net/entropo/tkP74/
.*
.*
non-comiqueIl n'y a vraiment pas besoin de regarder avant.
> /cow(.*?)milk/i.exec('My cow always gives milk');
["cow always gives milk", " always gives "]
J'ai pu obtenir ce dont j'avais besoin en utilisant la solution de Martinho Fernandes ci-dessous. Le code est:
var test = "My cow always gives milk";
var testRE = test.match("cow(.*)milk");
alert(testRE[1]);
Vous remarquerez que je préviens la variable testRE sous forme de tableau. En effet, testRE revient sous forme de tableau, pour une raison quelconque. La sortie de:
My cow always gives milk
Transforme en:
always gives
Utilisez simplement l'expression régulière suivante:
(?<=My cow\s).*?(?=\smilk)
La méthode match () recherche une correspondance dans une chaîne et renvoie un objet Array.
// Original string
var str = "My cow always gives milk";
// Using index [0] would return<br/>
// "**cow always gives milk**"
str.match(/cow(.*)milk/)**[0]**
// Using index **[1]** would return
// "**always gives**"
str.match(/cow(.*)milk/)[1]