Regex Correspond à tous les caractères entre deux chaînes


436

Exemple: "Ce n'est qu'une \ n simple phrase".

Je veux faire correspondre chaque caractère entre "Ceci est" et "phrase". Les sauts de ligne doivent être ignorés. Je ne peux pas comprendre la syntaxe correcte.


12
Vous voudrez peut-être indiquer dans quel environnement vous utilisez Regex. Il peut y avoir des différences selon ce que vous entendez exactement par «ignorer» les sauts de ligne.
Andrew Barber

Réponses:


647

Par exemple

(?<=This is)(.*)(?=sentence)

Regexr

J'ai utilisé lookbehind (?<=)et look ahead (?=)pour que "This is" et "sentence" ne soient pas inclus dans le match, mais cela dépend de votre cas d'utilisation, vous pouvez également simplement écrire This is(.*)sentence.

La chose importante ici est que vous activez le mode "dotall" de votre moteur regex, de sorte que le .correspond à la nouvelle ligne. Mais la façon dont vous procédez dépend de votre moteur d'expression régulière.

La prochaine chose est de savoir si vous utilisez .*ou .*?. Le premier est gourmand et correspondra jusqu'à la dernière "phrase" de votre chaîne, le second sera paresseux et correspondra jusqu'à la "phrase" suivante de votre chaîne.

Mise à jour

Regexr

This is(?s)(.*)sentence

Où le (? S) active le modificateur dotall, ce qui fait .correspondre les caractères de nouvelle ligne.

Mise à jour 2:

(?<=is \()(.*?)(?=\s*\))

correspond à votre exemple "Ceci est (une simple) phrase". Voir ici sur Regexr


@tchrist, désolé d'avoir dû chercher ça. Dois-je comprendre cela correctement et This is(?s)(.*)sentencefonctionnerait?
stema

@stema: Oui, cela devrait fonctionner pour activer le mode "dot all" dans la plupart des bibliothèques regex.
tchrist

1
Cela a principalement résolu mon problème, mais comment puis-je inclure un caractère d'espace blanc dans mon modèle? J'ai essayé ce qui suit: "(. *?) ())" Pour correspondre au ")" à la fin d'une séquence, mais cela n'a pas fonctionné.
0xbadf00d

28
Juste une note - regexr dit maintenant que lookbehind n'est pas pris en charge en javascript
Kovo

2
Existe-t-il un moyen de gérer les instances répétées de cette scission dans un bloc de texte? Pour exemple: "Ce n'est qu'une \ na phrase simple. Voici quelques trucs supplémentaires. C'est juste \ na une phrase simple. Et voici encore plus de trucs. C'est juste \ na une phrase simple.". Actuellement, il correspond à la chaîne entière, plutôt qu'à chaque instance.
jzadra

183

Quantificateur paresseux nécessaire

Ressusciter cette question parce que l'expression régulière de la réponse acceptée ne me semble pas tout à fait correcte. Pourquoi? Parce que

(?<=This is)(.*)(?=sentence)

correspondra my first sentence. This is my seconddansThis is my first sentence. This is my second sentence.

Voir la démo .

Vous avez besoin d'un quantificateur paresseux entre les deux contournements. L'ajout d'un ?rend la star paresseuse.

Cela correspond à ce que vous voulez:

(?<=This is).*?(?=sentence)

Voir la démo . J'ai supprimé le groupe de capture, ce qui n'était pas nécessaire.

Mode DOTALL pour faire correspondre les sauts de ligne

Notez que dans la démo, le "dot correspond au mode de saut de ligne" (aka) dot-all est défini (voir comment activer DOTALL dans différentes langues ). Dans de nombreuses versions regex, vous pouvez le définir avec le modificateur en ligne (?s), transformant l'expression en:

(?s)(?<=This is).*?(?=sentence)

Référence


Vous avez raison sur le groupe de capture. Je ne sais pas pourquoi j'ai fait ça. Mais la différence entre .*et .*?est également expliquée dans ma réponse (le paragraphe avant "Update"). Je ne pense donc pas que ma réponse soit incorrecte.
stema

2
@stema Désolé pour la piqûre, alors que je parcourais certaines de vos réponses hier, c'est la seule qui m'a fait trembler. :) J'ai adouci la première ligne de is incorrectà doesn't seem quite correct to me... J'espère que cela ne vous fait pas trembler, probablement juste une différence de perception sur ce que devrait être l'expression régulière d'une réponse à fort trafic.
zx81

39

Essayez This is[\s\S]*sentence, fonctionne en javascript


comment effectuer une recherche paresseuse de cette façon?
AGamePlayer

4
@AwQiruiGuo comme ci-dessus. [\s\S]*?(également appelé: caractère générique non gourmand)
phil294


13

utilisez ceci: (?<=beginningstringname)(.*\n?)(?=endstringname)


Je ne sais pas pourquoi tous les votes endstringname
positifs

J'ai trouvé utile de supprimer le début des lignes de journal (horodatage, etc.). J'ai utilisé une nouvelle ligne pour la chaîne de début et "at" pour la chaîne de fin.
Stan

2

Au cas où quelqu'un chercherait un exemple de cela dans un contexte Jenkins. Il analyse le build.log et s'il trouve une correspondance, il échoue la génération avec la correspondance.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

node{    
    stage("parse"){
        def file = readFile 'build.log'

        def regex = ~"(?s)(firstStringToUse(.*)secondStringToUse)"
        Matcher match = regex.matcher(file)
        match.find() {
            capturedText = match.group(1)
            error(capturedText)
        }
    }
}


1

Cela a fonctionné pour moi (j'utilise VS Code ):

pour: This is just\na simple sentence

Utilisation: This .+ sentence


0

Sublime Text 3x

Dans un texte sublime, vous écrivez simplement les deux mots que vous souhaitez conserver par exemple dans votre cas c'est

"C'est" et "phrase"

et vous écrivez. * entre les deux

c'est à dire This is .* sentence

et cela devrait vous faire du bien


Je ne suis pas sûr que la question porte sur la façon de procéder dans Sublime Text, mais fonctionne principalement dans Sublime Text. Cela ne fonctionne pas lorsqu'il se trouve qu'il y a un saut de ligne entre "Ceci est" et "phrase". De plus, le texte sublime sélectionne également "C'est" et "Phrase" plutôt que seulement le texte entre ces deux chaînes.
Dylan Kinnett

0

Voici comment je l'ai fait:
cela a été plus facile pour moi que d'essayer de trouver le regex spécifique nécessaire.

int indexPictureData = result.IndexOf("-PictureData:");
int indexIdentity = result.IndexOf("-Identity:");
string returnValue = result.Remove(indexPictureData + 13);
returnValue = returnValue + " [bytecoderemoved] " + result.Remove(0, indexIdentity); ` 

0

pour une recherche rapide dans VIM, vous pouvez utiliser à l'invite Vim Control: / Ceci est. * \ _. * phrase


0

J'ai atterri ici sur ma recherche de regex pour convertir cette syntaxe d'impression entre print "string", en Python2 dans les anciens scripts avec: print ("string"), pour Python3. Fonctionne bien, sinon utilisez 2to3.py pour des conversions supplémentaires. Voici ma solution pour les autres:

Essayez-le sur Regexr.com (ne fonctionne pas dans NP ++ pour une raison quelconque):

find:     (?<=print)( ')(.*)(')
replace: ('$2')

pour les variables:

(?<=print)( )(.*)(\n)
('$2')\n

pour étiquette et variable:

(?<=print)( ')(.*)(',)(.*)(\n)
('$2',$4)\n

Comment remplacer tous les "string" d'impression en Python2 par print ("string") pour Python3?


0

RegEx pour tout faire correspondre entre deux chaînes en utilisant l'approche Java.

List<String> results = new ArrayList<>(); //For storing results
String example = "Code will save the world";

Utilisons des objets Pattern et Matcher pour utiliser RegEx (. ?) * .

Pattern p = Pattern.compile("Code "(.*?)" world");   //java.util.regex.Pattern;
Matcher m = p.matcher(example);                      //java.util.regex.Matcher;

Étant donné que Matcher peut contenir plusieurs correspondances, nous devons parcourir les résultats et les stocker.

while(m.find()){   //Loop through all matches
   results.add(m.group()); //Get value and store in collection.
}

Cet exemple ne contiendra que "sauvera le" mot, mais dans le plus gros texte il trouvera probablement plus de correspondances.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.