Espressione regolare per estrarre il testo tra parentesi quadre


412

Domanda regex semplice. Ho una stringa nel seguente formato:

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

Qual è l'espressione regolare per estrarre le parole tra parentesi quadre, ad es.

sample
some
another one

Nota: nel mio caso d'uso, le parentesi non possono essere nidificate.

Risposte:


767

È possibile utilizzare la seguente regex a livello globale :

\[(.*?)\]

Spiegazione:

  • \[: [è un meta char e deve essere evitato se si desidera abbinarlo letteralmente.
  • (.*?) : abbina tutto in modo non avido e catturalo.
  • \]: ]è un meta char e deve essere evitato se si desidera abbinarlo letteralmente.

9
Il metodo dell'altra risposta, l'uso [^]]è più veloce di non-avido ( ?), e funziona anche con sapori regex che non supportano non-avidi. Tuttavia, i non avidi sembrano più belli.
Ipsquiggle

184
Come escludere [ ]dall'output (risultato)?
Mickey Tin,

9
@MickeyTin, se stai usando Java, puoi raggrupparlo usando group (1) su solo group (), quindi '[]' non andrà insieme
abyteneverlie

21
Questo corrisponde solo alla prima occorrenza
hfatahi,

9
Come si escludono le parentesi dal reso?
jzadra,

119
(?<=\[).+?(?=\])

Acquisirà il contenuto senza parentesi

  • (?<=\[) - lookbehind positivo per [

  • .*? - corrispondenza non avida per il contenuto

  • (?=\]) - lookahead positivo per ]

EDIT: per parentesi annidate il regex sottostante dovrebbe funzionare:

(\[(?:\[??[^\[]*?\]))

3
@igaurav L'ho verificato e funziona. Non funzionerà comunque in ambienti che non supportano lookbehinds come Javascript. Forse è il tuo caso?
Adam Moszczyński,

Adam, la tua soluzione tra parentesi annidate fallisce quando c'è una stringa con .dentro ...
patrick

89

Questo dovrebbe funzionare bene:

\[([^]]+)\]

5
Nel mio caso d'uso, il testo tra parentesi può includere nuove righe e questa regex funziona, mentre la risposta accettata no.
Dave,

1
cosa significa la classe di caratteri [^]]? Che cosa corrisponde?
Richard,

3
@Richard, Il ^ annulla la classe di caratteri. Significa "qualsiasi personaggio che non sia un]".
Jasonbar,

8
Penso che non funzioni come previsto, dovresti usare \[([^\[\]]*)\]per ottenere il contenuto nella parentesi più interna. Se si guarda in lfjlksd [ded[ee]22]poi \[([^]]+)\]si arriva [ded[ee]mentre l'espressione proposta sarebbe tornato [ee]. testede in link
TMC

1
Potete per favore fornire esempi 'sed' e 'awk' per usare questa regex ed estrarre il testo. Grazie.
valentt,

32

Le parentesi possono essere nidificate?

In caso contrario: \[([^]]+)\]corrisponde a un elemento, comprese le parentesi quadre. Backreference \1conterrà l'oggetto da abbinare. Se il tuo sapore regex supporta la ricerca, usa

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

Questo corrisponderà solo alla voce tra parentesi.


@KunalMukherjee: No, il regex può corrispondere un numero qualsiasi di volte. Ma è necessario dire esplicitamente ad alcuni tipi di regex di applicare ripetutamente il regex (ad esempio, usando il /gflag in JavaScript).
Tim Pietzcker,

14

Se non vuoi includere le parentesi nella corrispondenza, ecco la regex: (?<=\[).*?(?=\])

Analizziamolo

L' .corrisponde a qualsiasi carattere ad eccezione di terminatori di linea. Il ?=è un lookahead positivo . Un lookahead positivo trova una stringa quando una determinata stringa la segue. Il ?<=è un lookbehind positiva . Un lookbehind positivo trova una stringa quando una determinata stringa la precede. Per citare questo ,

Guarda avanti positivo (? =)

Trova l'espressione A dove segue l'espressione B:

A(?=B)

Guarda dietro positivo (? <=)

Trova l'espressione A dove l'espressione B precede:

(?<=B)A

L'alternativa

Se il tuo motore regex non supporta lookaheads e lookbehinds, puoi usare regex \[(.*?)\]per catturare le interiora delle parentesi in un gruppo e quindi puoi manipolare il gruppo come necessario.

Come funziona questa regex?

Le parentesi catturano i personaggi in un gruppo. Il .*?ottiene tutti i caratteri tra le parentesi quadre (ad eccezione di terminatori di linea, se non hai la sbandiera abilitato) in un modo che non è avido.


12

(?<=\[).*?(?=\])funziona bene come spiegato sopra. Ecco un esempio di 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'"

1
Dovresti sempre usare la formattazione del codice per le regex, ovunque appaiano. Se la regex è nel testo anziché in un blocco di codice, è possibile utilizzare i backtick per formattarli. ( ref )
Alan Moore,

1
Inoltre, la domanda riguardava le parentesi quadre ( []), non le parentesi.
Alan Moore,

6

Nel caso in cui tu abbia avuto parentesi sbilanciate , puoi probabilmente progettare un'espressione con ricorsione simile a,

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

che, ovviamente, si riferirebbe alla lingua o al motore RegEx che potresti utilizzare.

Demo RegEx 1


Oltre a quello,

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

Demo RegEx 2

o,

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

Demo RegEx 3

sono buone opzioni da esplorare.


Se desideri semplificare / modificare / esplorare l'espressione, è stata spiegata nel pannello in alto a destra di regex101.com . Se lo desideri, puoi anche guardare in questo link , come corrisponderebbe ad alcuni input di esempio.


Circuito RegEx

jex.im visualizza le espressioni regolari:

inserisci qui la descrizione dell'immagine

Test

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}`);
    });
}

fonte

Espressione regolare per abbinare parentesi bilanciate


4

se si desidera inserire solo una piccola lettera alfabetica tra parentesi quadra az

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

se vuoi lettere maiuscole e minuscole a-zA-Z

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

se vuoi maiuscoletti e lettera numerica a-zA-Z0-9

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

se vuoi tutto tra parentesi quadra

se vuoi testo, numero e simboli

(\[.*\])

3
([[][a-z \s]+[]])

Sopra dovrebbe funzionare data la seguente spiegazione

  • i caratteri tra parentesi quadre [] definiscono la classe characte, il che significa che il modello deve corrispondere almeno ad un carattere indicato tra parentesi quadre

  • \ s specifica uno spazio

  •  + indica almeno uno dei personaggi menzionati precedentemente in +.


In casi sensibili A-Zdovrebbe aggiungere al modello ([[][a-zA-Z \s]+[]]):; Penso che sia un buon modo, mentre \ in schemi regex che definiscono i segni di stringa ("e") e mescolano i neofiti mediante la barra rovesciata in "o" usi!
MohaMad

l'unica risposta che ha funzionato per me per regex C ++ (tranne che per farlo con virgolette anziché parentesi). std::regex pattern{R"(["][a-zA-Z \s]+["])"};
StackAttack,

3

Questo codice estrae il contenuto tra parentesi quadre e parentesi

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

(?: 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

3

In R, prova:

x <- 'foo[bar]baz'
str_replace(x, ".*?\\[(.*?)\\].*", "\\1")
[1] "bar"

..o gsub(pat, "\\1", x, perl=TRUE)dov'è patl'espressione regolare che hai fornito ..
Karsten W.

1

Per abbinare una sottostringa tra il primo [ e l' ultimo ] , è possibile utilizzare

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

Guarda una demo regex e una demo regex n . 2 .

Utilizzare le seguenti espressioni per abbinare le stringhe tra le parentesi quadre più vicine :

  • Comprese le parentesi:

    • \[[^][]*]- PCRE, Python re/ regex, .NET, Golang, POSIX (grep, sed, bash)
    • \[[^\][]*]- ECMAScript (JavaScript, C ++ std::regex, VBA RegExp)
    • \[[^\]\[]*] - Java regex
    • \[[^\]\[]*\] - Onigmo (Ruby, richiede la fuga di parentesi ovunque)
  • Escluse le parentesi:

    • (?<=\[)[^][]*(?=])- Software PCRE, Python re/ regex, .NET (C #, ecc.), ICU (R stringr), JGSoft
    • \[([^][]*)]- Bash , Golang - cattura il contenuto tra parentesi quadre con una coppia di parentesi non salvate, vedi anche sotto
    • \[([^\][]*)]- JavaScript , C ++std::regex , VBARegExp
    • (?<=\[)[^\]\[]*(?=]) - Java regex
    • (?<=\[)[^\]\[]*(?=\]) - Onigmo (Ruby, richiede la fuga di parentesi ovunque)

NOTA : *corrisponde a 0 o più caratteri, utilizzare +per abbinare 1 o più caratteri per evitare corrispondenze di stringhe vuote nell'elenco / matrice risultante.

Ogni volta che è disponibile il supporto per entrambe le soluzioni, le soluzioni precedenti si basano su di esse per escludere la parentesi aperta / finale aperta / chiusa. In caso contrario, fare affidamento sui gruppi di acquisizione (sono stati forniti collegamenti alle soluzioni più comuni in alcune lingue).

Se devi abbinare le parentesi nidificate , potresti vedere le soluzioni nell'espressione regolare per abbinare il thread tra parentesi bilanciate e sostituire le parentesi tonde con quelle quadrate per ottenere la funzionalità necessaria. È necessario utilizzare i gruppi di acquisizione per accedere ai contenuti con parentesi aperta / chiusa esclusa:


0

Avevo bisogno di includere le nuove righe e le parentesi

\[[\s\S]+\]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.