Expression régulière pour extraire le texte entre crochets

412

Question regex simple. J'ai une chaîne au format suivant:

this is a [sample] string with [some] special words. [another one]

Quelle est l'expression régulière pour extraire les mots entre crochets, c.-à-d.

sample
some
another one

Remarque: Dans mon cas d'utilisation, les crochets ne peuvent pas être imbriqués.

Obi Wan Kenobi
la source

Réponses:

767

Vous pouvez utiliser globalement l' expression régulière suivante :

\[(.*?)\]

Explication:

  • \[: [est un méta-caractère et doit être échappé si vous voulez le faire correspondre littéralement.
  • (.*?) : associez tout de manière non gourmande et capturez-le.
  • \]: ]est un méta-caractère et doit être échappé si vous voulez le faire correspondre littéralement.
codaddict
la source
9
L'autre méthode de réponse, utilisant [^]]est plus rapide que non-gourmand ( ?), et fonctionne également avec des saveurs regex qui ne prennent pas en charge les non-gourmands. Cependant, les non gourmands sont plus beaux.
Ipsquiggle
184
Comment exclure [ ]de la sortie (résultat)?
Mickey Tin
9
@MickeyTin, si vous utilisez Java, vous pouvez le grouper en utilisant le groupe (1) sur juste le groupe (), donc le '[]' ne fonctionnera pas ensemble
abyteneverlie
21
Cela ne correspond qu'à la première occurrence
hfatahi
9
Comment exclure les parenthèses de la déclaration?
jzadra
119
(?<=\[).+?(?=\])

Capture le contenu sans crochets

  • (?<=\[) - lookbehind positif pour [

  • .*? - match non gourmand pour le contenu

  • (?=\]) - anticipation positive pour ]

EDIT: pour les crochets imbriqués, l'expression régulière ci-dessous devrait fonctionner:

(\[(?:\[??[^\[]*?\]))
Adam Moszczyński
la source
3
@igaurav Je l'ai vérifié et cela fonctionne. Il ne fonctionnera cependant pas dans des environnements qui ne prennent pas en charge les lookbehinds comme Javascript. C'est peut-être votre cas?
Adam Moszczyński
Adam, votre solution de parenthèses imbriquées échoue quand il y a une chaîne avec un .dedans ...
patrick
89

Cela devrait fonctionner correctement:

\[([^]]+)\]
jasonbar
la source
5
Dans mon cas d'utilisation, le texte entre crochets peut inclure de nouvelles lignes, et cette expression régulière fonctionne, contrairement à la réponse acceptée.
Dave
1
que signifie la classe de caractères [^]]? À quoi cela correspond-il?
Richard
3
@Richard, le ^ annule la classe de caractère. Cela signifie "tout caractère qui n'est pas un]".
jasonbar
8
Je pense que cela ne fonctionne pas comme prévu, vous devez utiliser \[([^\[\]]*)\]pour obtenir le contenu dans le support le plus interne. Si vous regardez dans lfjlksd [ded[ee]22]alors \[([^]]+)\]vous obtiendrez [ded[ee]alors l'expression proposée reviendrait [ee]. testé dans le lien
TMC
1
Pouvez-vous fournir des exemples «sed» et «awk» pour utiliser cette expression régulière et extraire du texte. Merci.
valentt
32

Les supports peuvent-ils être imbriqués?

Sinon: \[([^]]+)\]correspond à un élément, y compris les crochets. La référence arrière \1contiendra l'élément à faire correspondre. Si votre saveur regex prend en charge le lookaround, utilisez

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

Cela ne correspondra qu'à l'élément entre parenthèses.

Tim Pietzcker
la source
@KunalMukherjee: Non, l'expression régulière peut correspondre à un certain nombre de fois. Mais certaines saveurs d'expression régulière doivent être expliquées explicitement pour appliquer l'expression régulière à plusieurs reprises (par exemple, en utilisant l' /gindicateur en JavaScript).
Tim Pietzcker
14

Si vous ne souhaitez pas inclure les parenthèses dans la correspondance, voici l'expression régulière: (?<=\[).*?(?=\])

Décomposons-le

Le .correspond à n'importe quel caractère à l'exception des terminateurs de ligne. Le ?=est une anticipation positive . Un lookahead positif trouve une chaîne quand une certaine chaîne vient après. C'est ?<=un regard positif derrière . Un lookbehind positif trouve une chaîne lorsqu'une certaine chaîne la précède. Pour citer ceci ,

Regardez vers l'avenir positif (? =)

Trouvez l'expression A où l'expression B suit:

A(?=B)

Regardez derrière positif (? <=)

Rechercher l'expression A où l'expression B précède:

(?<=B)A

L'alternative

Si votre moteur regex ne prend pas en charge les lookaheads et lookbehinds, vous pouvez utiliser l'expression régulière \[(.*?)\]pour capturer les entrailles des crochets dans un groupe, puis vous pouvez manipuler le groupe si nécessaire.

Comment fonctionne cette expression régulière?

Les parenthèses capturent les personnages d'un groupe. Le .*?obtient tous les caractères entre les crochets (sauf pour les terminateurs de ligne, sauf si le sdrapeau est activé) d'une manière qui n'est pas gourmande.

LJ Germain
la source
12

(?<=\[).*?(?=\])fonctionne bien selon l'explication donnée ci-dessus. Voici un exemple Python:

import re 
str = "Pagination.go('formPagination_bottom',2,'Page',true,'1',null,'2013')"
re.search('(?<=\[).*?(?=\])', str).group()
"'formPagination_bottom',2,'Page',true,'1',null,'2013'"
devd
la source
1
Vous devez toujours utiliser la mise en forme du code pour les expressions régulières, où qu'elles apparaissent. Si l'expression régulière se trouve dans le texte plutôt que dans un bloc de code, vous pouvez utiliser des raccourcis pour les formater. ( ref )
Alan Moore
1
En outre, la question concernait les crochets ( []), pas les parenthèses.
Alan Moore
6

Juste au cas où vous auriez pu avoir des parenthèses déséquilibrées , vous pouvez probablement concevoir une expression avec une récursion similaire à,

\[(([^\]\[]+)|(?R))*+\]

ce qui, bien sûr, serait lié à la langue ou au moteur RegEx que vous pourriez utiliser.

RegEx Demo 1


Autre que ça,

\[([^\]\[\r\n]*)\]

RegEx Demo 2

ou,

(?<=\[)[^\]\[\r\n]*(?=\])

RegEx Demo 3

sont de bonnes options à explorer.


Si vous souhaitez simplifier / modifier / explorer l'expression, cela a été expliqué dans le panneau supérieur droit de regex101.com . Si vous le souhaitez, vous pouvez également regarder dans ce lien , comment cela se comparerait à certains exemples d'entrées.


Circuit RegEx

jex.im visualise les expressions régulières:

entrez la description de l'image ici

Tester

const regex = /\[([^\]\[\r\n]*)\]/gm;
const str = `This is a [sample] string with [some] special words. [another one]
This is a [sample string with [some special words. [another one
This is a [sample[sample]] string with [[some][some]] special words. [[another one]]`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

La source

Expression régulière pour correspondre à des parenthèses équilibrées

Emma
la source
4

si vous voulez seulement une petite lettre de l'alphabet entre crochets az

(\[[a-z]*\])

si vous voulez des lettres minuscules et majuscules a-zA-Z

(\[[a-zA-Z]*\]) 

si vous voulez des petites majuscules et une lettre numérique a-zA-Z0-9

(\[[a-zA-Z0-9]*\]) 

si vous voulez tout entre crochets

si vous voulez du texte, des chiffres et des symboles

(\[.*\])
ßãlãjî
la source
3
([[][a-z \s]+[]])

Ci-dessus devrait fonctionner compte tenu de l'explication suivante

  • les caractères entre crochets [] définit la classe characte, ce qui signifie que le modèle doit correspondre au moins à un caractère mentionné entre crochets

  • \ s spécifie un espace

  •  + signifie au moins un des caractères mentionnés précédemment pour +.

fantômes
la source
Dans les cas sensibles, A-Zajouter au motif ([[][a-zA-Z \s]+[]]):; Je pense que c'est une bonne façon, alors que \ dans les modèles regex qui définissent les marques de chaîne ("et ') et mélangent les débutants en gérant la barre oblique inverse dans les utilisations" ou "!
MohaMad
la seule réponse qui a fonctionné pour moi pour l'expression régulière C ++ (sauf que je le fais avec des citations au lieu de crochets). std::regex pattern{R"(["][a-zA-Z \s]+["])"};
StackAttack
3

Ce code extraira le contenu entre crochets et parenthèses

(?:(?<=\().+?(?=\))|(?<=\[).+?(?=\]))

(?: non capturing group
(?<=\().+?(?=\)) positive lookbehind and lookahead to extract the text between parentheses
| or
(?<=\[).+?(?=\]) positive lookbehind and lookahead to extract the text between square brackets
Nezar Fadle
la source
3

Dans R, essayez:

x <- 'foo[bar]baz'
str_replace(x, ".*?\\[(.*?)\\].*", "\\1")
[1] "bar"
Tony Ladson
la source
..ou gsub(pat, "\\1", x, perl=TRUE), où patest l'expression régulière que vous avez fournie ..
Karsten W.
1

Pour faire correspondre une sous - [ ] chaîne entre la première et la dernière , vous pouvez utiliser

\[.*\]            # Including open/close brackets
\[(.*)\]          # Excluding open/close brackets (using a capturing group)
(?<=\[).*(?=\])   # Excluding open/close brackets (using lookarounds)

Voir une démo regex et une démo regex # 2 .

Utilisez les expressions suivantes pour faire correspondre les chaînes entre les crochets les plus proches :

  • Y compris les supports:

    • \[[^][]*]- PCRE, Python re/ regex, .NET, Golang, POSIX (grep, sed, bash)
    • \[[^\][]*]- ECMAScript (JavaScript, C ++ std::regex, VBA RegExp)
    • \[[^\]\[]*] - Java regex
    • \[[^\]\[]*\] - Onigmo (Ruby, nécessite l'échappement des supports partout)
  • À l'exclusion des parenthèses:

    • (?<=\[)[^][]*(?=])- PCRE, Python re/ regex, .NET (C #, etc.), ICU (R stringr), logiciel JGSoft
    • \[([^][]*)]- Bash , Golang - capturez le contenu entre crochets avec une paire de parenthèses non échappées, voir aussi ci-dessous
    • \[([^\][]*)]- JavaScript , C ++std::regex , VBARegExp
    • (?<=\[)[^\]\[]*(?=]) - Java regex
    • (?<=\[)[^\]\[]*(?=\]) - Onigmo (Ruby, nécessite l'échappement des supports partout)

REMARQUE : *correspond à 0 ou plusieurs caractères, utilisez +pour correspondre à 1 ou plus pour éviter les correspondances de chaînes vides dans la liste / le tableau résultant.

Chaque fois que la prise en charge des deux contournements est disponible, les solutions ci-dessus s'appuient sur elles pour exclure le crochet d'ouverture / fermeture avant / arrière. Sinon, comptez sur la capture de groupes (des liens vers les solutions les plus courantes dans certaines langues ont été fournis).

Si vous devez faire correspondre des parenthèses imbriquées , vous pouvez voir les solutions dans l' expression régulière pour faire correspondre le thread entre parenthèses équilibrées et remplacer les crochets ronds par les carrés pour obtenir les fonctionnalités nécessaires. Vous devez utiliser des groupes de capture pour accéder au contenu avec le crochet ouvert / fermé exclu:

Wiktor Stribiżew
la source
0

J'avais besoin d'inclure des nouvelles lignes et d'inclure les crochets

\[[\s\S]+\]

citynorman
la source