Expression régulière pour rechercher une chaîne incluse entre deux caractères tout en excluant les délimiteurs


295

J'ai besoin d'extraire d'une chaîne un ensemble de caractères qui sont inclus entre deux délimiteurs, sans retourner les délimiteurs eux-mêmes.

Un exemple simple devrait être utile:

Cible : extraire la sous-chaîne entre crochets, sans renvoyer les crochets eux-mêmes.

Chaîne de base :This is a test string [more or less]

Si j'utilise le reg suivant. ex.

\ [. *? \]

Le match est [more or less]. Je dois obtenir seulement more or less(sans les crochets).

Est-il possible de le faire?


Réponses:


454

Facile à faire:

(?<=\[)(.*?)(?=\])

Techniquement, cela utilise des lookaheads et des lookbehinds. Voir Lookahead et Lookbehind Zero-Width Assertions . Le motif se compose de:

  • est précédé d'un [qui n'est pas capturé (lookbehind);
  • un groupe capturé non gourmand. Il n'est pas gourmand de s'arrêter au premier]; et
  • est suivi d'un] qui n'est pas capturé (lookahead).

Alternativement, vous pouvez simplement capturer ce qui se trouve entre les crochets:

\[(.*?)\]

et renvoyez le premier groupe capturé au lieu du match entier.


138
"Facile à faire", LOL! :) Les expressions régulières me donnent toujours des maux de tête, j'ai tendance à les oublier dès que je trouve celles qui résolvent mes problèmes. À propos de vos solutions: la première fonctionne comme prévu, la seconde ne fonctionne pas, elle continue à inclure les crochets. J'utilise C #, peut-être que l'objet RegEx a sa propre "saveur" de moteur regex ...
Diego

5
C'est parce que vous regardez l'ensemble du match plutôt que le premier groupe correspondant.
cletus

Merci beaucoup, site très utile! Je vais le garder comme référence. :) Désolé si j'ai fait une certaine confusion, le développement C # n'est pas vraiment une de mes compétences ..
Diego

1
Est-ce que cela fonctionne si la sous-chaîne contient également les délimiteurs? Par exemple dans This is a test string [more [or] less]ce retour more [or] less?
gnzlbg

1
@gnzlbg non, il retournerait "plus [ou"
MerickOWA

53

Si vous utilisez JavaScript , la première solution fournie par cletus, (?<=\[)(.*?)(?=\])ne fonctionnera pas, car JavaScript ne prend pas en charge l'opérateur Lookbehind.

Cependant, la deuxième solution fonctionne bien, mais vous devez obtenir le deuxième élément correspondant.

Exemple:

var regex = /\[(.*?)\]/;
var strToMatch = "This is a test string [more or less]";
var matched = regex.exec(strToMatch);

Il renverra:

["[more or less]", "more or less"]

Donc, ce dont vous avez besoin est la deuxième valeur. Utilisation:

var matched = regex.exec(strToMatch)[1];

Rendre:

"more or less"

2
que faire s'il y a plusieurs correspondances de [plus ou moins] dans la chaîne?

Des assertions de lookbehind ont été ajoutées à RegExp dans ES2018
TheDarkIn1978

19

Il vous suffit de «capturer» le bit entre les crochets.

\[(.*?)\]

Pour le capturer, mettez-le entre parenthèses. Vous ne dites pas quelle langue cela utilise. En Perl par exemple, vous y accéderez en utilisant la variable $ 1.

my $string ='This is the match [more or less]';
$string =~ /\[(.*?)\]/;
print "match:$1\n";

D'autres langues auront des mécanismes différents. C #, par exemple, utilise la classe de collection Match , je crois.


Merci, mais cette solution n'a pas fonctionné, elle continue d'inclure les crochets. Comme je l'ai écrit dans mon commentaire sur la solution de Cletus, il se pourrait que l'objet C # RegEx l'interprète différemment. Je ne suis pas expert en C #, donc ce n'est qu'une conjecture, c'est peut-être juste mon manque de connaissances. :)
Diego

11

[^\[] Correspond à n'importe quel caractère qui n'est pas [.

+Faites correspondre 1 ou plus de tout ce qui ne l'est pas [. Crée des groupes de ces correspondances.

(?=\])Anticipation positive ]. Correspond à un groupe se terminant par ]sans l'inclure dans le résultat.

Terminé.

[^\[]+(?=\])

Preuve.

http://regexr.com/3gobr

Similaire à la solution proposée par null. Mais le supplément \]n'est pas requis. Comme note supplémentaire, il ne semble \pas nécessaire de s'échapper [après ^. Pour plus de lisibilité, je le laisserais dedans.

Ne fonctionne pas dans la situation où les délimiteurs sont identiques. "more or less"par exemple.


8

PHP:

$string ='This is the match [more or less]';
preg_match('#\[(.*)\]#', $string, $match);
var_dump($match[1]);


3

J'ai eu le même problème en utilisant regex avec les scripts bash. J'ai utilisé une solution en 2 étapes en utilisant des tuyaux avec grep -o en appliquant

 '\[(.*?)\]'  

d'abord, puis

'\b.*\b'

Évidemment pas aussi efficace pour les autres réponses, mais une alternative.


3

Celui-ci fonctionne spécifiquement pour l'analyseur d'expressions régulières de javascript /[^[\]]+(?=])/g

il suffit d'exécuter cela dans la console

var regex = /[^[\]]+(?=])/g;
var str = "This is a test string [more or less]";
var match = regex.exec(str);
match;

2

Je voulais trouver une chaîne entre / et #, mais # est parfois facultatif. Voici l'expression régulière que j'utilise:

  (?<=\/)([^#]+)(?=#*)

0

Voici comment je me suis débrouillé sans «[» et «]» en C #:

        var text = "This is a test string [more or less]";
        //Getting only string between '[' and ']'
        Regex regex = new Regex(@"\[(.+?)\]");
        var matchGroups = regex.Matches(text);
        for (int i = 0; i < matchGroups.Count; i++)
        {
            Console.WriteLine(matchGroups[i].Groups[1]);
        }

La sortie est:

more or less

-1

Si vous avez besoin d'extraire le texte sans les crochets, vous pouvez utiliser bash awk

echo " [hola mundo] " | awk -F'[][]' '{print $2}'

résultat:

hola mundo

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.