J'ai trouvé des articles très similaires, mais je ne peux pas tout à fait obtenir mon expression régulière ici.
J'essaye d'écrire une expression régulière qui renvoie une chaîne qui se trouve entre deux autres chaînes. Par exemple: je veux obtenir la chaîne qui se trouve 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 renvoie la chaîne "la vache donne toujours".
javascript
regex
string
phil
la source
la source
Réponses:
Une anticipation (cette
(?=
partie) ne consomme aucune entrée. Il s'agit d'une assertion de largeur nulle (tout comme les vérifications de limites et les regards en arrière).Vous voulez un match régulier ici, pour consommer la
cow
portion. Pour capturer la partie intermédiaire, vous utilisez un groupe de capture (mettez simplement la partie du motif que vous souhaitez capturer entre parenthèses):Aucun lookahead n'est nécessaire du tout.
la source
matched[1]
, et non tout le texte correspondant avecmatched[0]
.([\s\S]*?)
plutôt que(.*?)
.La solution la plus complète qui fonctionnera dans la grande majorité des cas utilise un groupe de capture avec un modèle de correspondance de points paresseux . Cependant, un point
.
dans l'expression régulière JavaScript ne correspond pas aux caractères de saut de ligne, donc, ce qui fonctionnera dans 100% des cas est une construction[^]
ou[\s\S]
/[\d\D]
/[\w\W]
.ECMAScript 2018 et solution compatible plus récente
Dans les environnements JavaScript prenant en charge ECMAScript 2018 , le
s
modificateur permet de.
faire correspondre n'importe quel caractère, y compris les caractères de saut de ligne, et le moteur regex prend en charge les lookbehinds de longueur variable. Donc, vous pouvez utiliser une expression régulière commeDans les deux cas, la position actuelle est vérifiée
cow
avec n'importe quel 1/0 ou plus d'espaces blancs aprèscow
, puis tous les caractères 0+ aussi peu que possible sont mis en correspondance et consommés (= ajouté à la valeur de correspondance), puismilk
est vérifié (avec n'importe quel 1/0 ou plus d'espaces blancs avant cette sous-chaîne).Scénario 1: entrée sur une seule ligne
Ce scénario et tous les autres scénarios ci-dessous sont pris en charge par tous les environnements JavaScript. Voir des exemples d'utilisation au bas de la réponse.
cow
se trouve d' abord, puis un espace, puis tout 0+ caractères autres que les caractères de saut de ligne, aussi peu que possible*?
est un quantificateur paresseux, sont capturés dans le Groupe 1, puis un espace avecmilk
suivi incontournable (et ceux qui sont en correspondance et consommaient aussi ).Scénario 2: entrée multiligne
Ici,
cow
et un espace est 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 avecmilk
sont mis en correspondance.Scénario 3: correspondances qui se chevauchent
Si vous avez une chaîne comme
>>>15 text>>>67 text2>>>
et que vous avez besoin d'obtenir 2 correspondances entre>>>
+number
+whitespace
et>>>
, vous ne pouvez pas l'utiliser/>>>\d+\s(.*?)>>>/g
car cela ne trouvera qu'une seule correspondance car l'>>>
avant67
est déjà consommé lors de la recherche de la première correspondance. Vous pouvez utiliser une anticipation positive pour vérifier la présence du texte sans réellement «l'avaler» (c'est-à-dire l'ajouter à la correspondance):Voir la démo en ligne regex rendement
text1
et dutext2
groupe 1 contenus trouvés.Consultez également Comment obtenir toutes les correspondances qui se chevauchent pour une chaîne .
Considérations relatives aux performances
Le motif de correspondance de points paresseux (
.*?
) à l'intérieur des modèles de regex peut ralentir l'exécution du script si une entrée très longue est donnée. Dans de nombreux cas, la technique du déroulement de la boucle aide dans une plus grande mesure. En essayant de saisir tout entrecow
etmilk
depuis"Their\ncow\ngives\nmore\nmilk"
, nous voyons que nous avons juste besoin de faire correspondre toutes les lignes qui ne commencent pas parmilk
, donc, au lieu decow\n([\s\S]*?)\nmilk
nous pouvons utiliser:Voir la démo regex (s'il y en a
\r\n
, utilisez/cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). Avec cette petite chaîne de test, le gain de performances est négligeable, mais avec du texte très volumineux, vous sentirez la différence (surtout si les lignes sont longues et les sauts de ligne peu nombreux).la source
Voici une expression régulière qui saisira ce qui se trouve entre la vache et le lait (sans espace de début / de fin):
Un exemple: http://jsfiddle.net/entropo/tkP74/
la source
.*
.*
nonIl n'y a vraiment pas besoin de regarder avant.
la source
La réponse choisie n'a pas fonctionné pour moi ... hmm ...
Ajoutez simplement de l'espace après la vache et / ou avant le lait pour couper les espaces de "donne toujours"
la source
?<=
n'est pas pris en charge en Javascript.J'ai pu obtenir ce dont j'avais besoin en utilisant la solution de Martinho Fernandes ci-dessous. Le code est:
Vous remarquerez que j'alerte la variable testRE sous forme de tableau. C'est parce que testRE revient sous forme de tableau, pour une raison quelconque. La sortie de:
Se transforme en:
la source
Utilisez simplement l'expression régulière suivante:
la source
?<=
n'est pas pris en charge en Javascript. Ce serait le moyen de le faire cependant.Je trouve que l'expression régulière est fastidieuse et prend du temps compte tenu de la syntaxe. Puisque vous utilisez déjà javascript, il est plus facile de faire ce qui suit sans regex:
la source
Si les données sont sur plusieurs lignes, vous devrez peut-être utiliser ce qui suit,
Exemple Regex 101
la source
La méthode match () recherche une chaîne pour une correspondance et renvoie un objet Array.
la source
Tâche
Extraire la sous-chaîne entre deux chaînes (à l'exclusion de ces deux chaînes)
Solution
la source