Espressione regolare per trovare una stringa inclusa tra due caratteri mentre ESCLUDE i delimitatori


294

Ho bisogno di estrarre da una stringa un set di caratteri che sono inclusi tra due delimitatori, senza restituire i delimitatori stessi.

Un semplice esempio dovrebbe essere utile:

Target : estrae la sottostringa tra parentesi quadre, senza restituire le parentesi stesse.

Stringa di base :This is a test string [more or less]

Se uso il seguente reg. ex.

\ [. *? \]

La partita è [more or less]. Ho bisogno di ottenere solo more or less(senza le parentesi).

È possibile farlo?


Risposte:


453

Facile fatto:

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

Tecnicamente sta usando lookaheads e lookbehinds. Vedi le asserzioni di larghezza zero di Lookahead e Lookbehind . Il modello è costituito da:

  • è preceduto da un [che non viene catturato (lookbehind);
  • un gruppo catturato non avido. Non è avido fermarsi al primo]; e
  • è seguito da un] che non viene catturato (lookahead).

In alternativa puoi semplicemente catturare ciò che è tra le parentesi quadre:

\[(.*?)\]

e restituisce il primo gruppo acquisito anziché l'intera partita.


138
"Facile", LOL! :) Le espressioni regolari mi fanno sempre venire il mal di testa, tendo a dimenticarle non appena trovo quelle che risolvono i miei problemi. Informazioni sulle soluzioni: la prima funziona come previsto, la seconda no, continua a includere le parentesi. Sto usando C #, forse l'oggetto RegEx ha il suo "sapore" di regex engine ...
Diego,

5
Lo sta facendo perché stai guardando l'intera partita anziché il primo gruppo abbinato.
cletus,

Mille grazie, sito molto utile! Lo terrò come riferimento. :) Scusami se ho fatto un po 'di confusione, lo sviluppo di C # non è davvero una delle mie abilità ..
Diego,

1
Funziona se la sottostringa contiene anche i delimitatori? Ad esempio in This is a test string [more [or] less]questo ritorno more [or] less?
gnzlbg,

1
@gnzlbg no, restituirebbe "more [o"
MerickOWA il

52

Se si utilizza JavaScript , la prima soluzione fornita da cletus, (?<=\[)(.*?)(?=\])non funzionerà perché JavaScript non supporta l'operatore lookbehind.

Tuttavia, la seconda soluzione funziona bene, ma è necessario ottenere il secondo elemento corrispondente.

Esempio:

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

Restituirà:

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

Quindi, ciò di cui hai bisogno è il secondo valore. Uso:

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

Ritornare:

"more or less"

2
cosa succede se ci sono più corrispondenze di [più o meno] nella stringa?

Le affermazioni di Lookbehind sono state aggiunte a RegExp in ES2018
TheDarkIn1978

19

Hai solo bisogno di 'catturare' il bit tra le parentesi.

\[(.*?)\]

Per catturarlo mettilo tra parentesi. Non dici quale lingua sta usando. Ad esempio, in Perl, accederai a questo usando la variabile $ 1.

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

Altre lingue avranno meccanismi diversi. C #, ad esempio, usa la classe di raccolta Match , credo.


Grazie, ma questa soluzione non ha funzionato, continua a includere le parentesi quadre. Come ho scritto nel mio commento alla soluzione di Cletus, è possibile che l'oggetto C # RegEx lo interpreti in modo diverso. Non sono esperto di C #, quindi è solo una congettura, forse è solo la mia mancanza di conoscenza. :)
Diego,

11

[^\[] Abbina qualsiasi personaggio che non sia [.

+Abbina 1 o più di tutto ciò che non lo è [. Crea gruppi di queste partite.

(?=\])Lookahead positivo ]. Abbina un gruppo che termina ]senza includerlo nel risultato.

Fatto.

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

Prova.

http://regexr.com/3gobr

Simile alla soluzione proposta da null. Ma l'ulteriore \]non è richiesto. Come nota aggiuntiva, sembra che \non sia necessario sfuggire al [dopo il ^. Per leggibilità, lo lascerei dentro.

Non funziona nella situazione in cui i delimitatori sono identici. "more or less"per esempio.


8

PHP:

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


3

Ho avuto lo stesso problema usando regex con script bash. Ho usato una soluzione in 2 passaggi usando tubi con grep -o application

 '\[(.*?)\]'  

prima poi

'\b.*\b'

Ovviamente non altrettanto efficiente nelle altre risposte, ma un'alternativa.


3

Questo funziona specificamente per il parser di espressioni regolari javascript /[^[\]]+(?=])/g

basta eseguirlo nella console

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

2

Volevo trovare una stringa tra / e #, ma # a volte è facoltativo. Ecco la regex che uso:

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

0

Ecco come sono arrivato senza '[' e ']' in 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]);
        }

L'output è:

more or less

-1

Se è necessario estrarre il testo senza le parentesi, è possibile utilizzare bash awk

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

risultato:

hola mundo

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.