2010-06-18 5 views
6

Comment puis-je utiliser regex pour trouver tout le texte avant le texte "Tout le texte avant cette ligne sera inclus"?trouver tout le texte avant d'utiliser regex

Je comprend un exemple de texte ci-dessous par exemple

This can include deleting, updating, or adding records to your database, which would then be reflex. 

All text before this line will be included 

You can make this a bit more sophisticated by encrypting the random number and then verifying that it is still a number when it is decrypted. Alternatively, you can pass a value and a key instead. 

Répondre

9
(.*?)All text before this line will be included 

Selon ce cadre régulier particulier l'expression que vous utilisez, vous devrez peut-être inclure un drapeau pour indiquer que . peut correspondre à des sauts de ligne ainsi que.

Le premier (et le seul) sous-groupe comprendra le texte correspondant. La façon dont vous extrayez cela dépendra à nouveau du langage et du cadre d'expression régulière que vous utilisez.

Si vous voulez inclure le texte "Tout le texte avant cette ligne ...", alors le match entier est ce que vous voulez.

+1

Ce match * inclura * le texte "Tout le texte avant que cette ligne ne soit incluse" - ce n'est pas clair si cela est désiré de la question originale, mais voir ma réponse sur la façon de l'exclure sinon. –

+1

Je voulais dire que le premier sous-groupe comprendrait le texte correspondant. Je vais modifier pour clarifier. – VoteyDisciple

+1

Oui, mais je dirais que lookahead est conceptuellement plus proche de ce qui est voulu (et donc meilleure option). Bien sûr, lookahead n'est pas toujours disponible, mais si vous ne l'avez pas, vous n'avez probablement pas de correspondance paresseuse non plus ... J'ai essayé d'ajouter toutes ces informations à ma réponse, j'espère que c'est fait clairement. –

1

Cela devrait le faire:

<?php 
$str = "This can include deleting, updating, or adding records to your database, which would then be reflex. 

All text before this line will be included 

You can make this a bit more sophisticated by encrypting the random number and then verifying that it is still a number when it is decrypted. Alternatively, you can pass a value and a key instead."; 

echo preg_filter("/(.*?)All text before this line will be included.*/s","\\1",$str); 
?> 

Retours:

This can include deleting, updating, or adding records to your database, which would then be reflex. 
11

À partir d'une explication ... Aller à la fin des réponses rapides

Pour correspondre jusqu'à un morceau spécifique de texte, et confirmez qu'il est là mais ne l'incluez pas avec le match, vous pouvez utiliser un lookahead positif, en utilisant la notation (?=regex)

Ceci confirme que 'regex' existe à cette position, mais correspond seulement à la position de départ, pas au contenu de celle-ci.

Alors, cela nous donne l'expression:

.*?(?=All text before this line will be included) 

. est un caractère et *? est un match paresseux (consomme moins possible, par rapport à * régulière qui consomme le plus faible possible).

Cependant, dans presque toutes les expressions regex, . exclura le saut de ligne, nous devons donc utiliser explicitement un indicateur pour inclure les nouvelles lignes. Le drapeau à utiliser est s, (qui signifie "mode ligne unique", bien qu'il soit également appelé mode "DOTALL" dans certaines versions).

Et cela peut être mis en œuvre de diverses manières, y compris ...

À l'échelle mondiale, pour/regexes: à base

/regex/s 

Inline, global pour les regex:

(?s)regex 

En ligne, s'applique uniquement à la partie entre crochets:

(?s:reg)ex 

Et en tant qu'argument de fonction (dépend de la langue avec laquelle vous faites la regex).

Alors, sans doute l'expression rationnelle que vous voulez est ceci:

(?s).*?(?=All text before this line will be included) 


Cependant, il y a des mises en garde:

Tout d'abord, toutes les saveurs regex soutiennent quantificateurs paresseux - vous pourriez avoir à utiliser seulement .*, (ou potentiellement utiliser une logique plus complexe en fonction des exigences précises si "Tout le texte avant ... "peut apparaître plusieurs fois). En second lieu, tous les styles de regex ne supportent pas les lookaheads, vous devrez donc utiliser les groupes capturés pour obtenir le texte que vous voulez.

Enfin, vous ne pouvez pas toujours spécifier des drapeaux, comme le s ci-dessus, donc peut-être soit correspondance « quoi que ce soit ou retour à la ligne » (.|\n) ou peut-être [\s\S] (espaces et pas des espaces) pour obtenir l'équivalent correspondant.

Si vous êtes limité par tous ces (je pense que la mise en œuvre XML est), alors vous aurez à faire:

([\s\S]*)All text before this line will be included 

Et puis extraire le premier sous-groupe du résultat du match.

+0

Ah, merci, c'est utile de savoir! – vimist

+0

trop mauvais l'OP n'a jamais accepté une réponse. tous ont été très utiles pour moi. – helgatheviking

Questions connexes