Regulärer Ausdruck, um eine Zeichenfolge zwischen zwei Zeichen zu finden, während die Trennzeichen ausgeschlossen werden


294

Ich muss aus einer Zeichenfolge eine Reihe von Zeichen extrahieren, die zwischen zwei Trennzeichen enthalten sind, ohne die Trennzeichen selbst zurückzugeben.

Ein einfaches Beispiel sollte hilfreich sein:

Ziel : Extrahieren Sie die Teilzeichenfolge zwischen eckigen Klammern, ohne die Klammern selbst zurückzugeben.

Basiszeichenfolge :This is a test string [more or less]

Wenn ich die folgende reg benutze. Ex.

\ [. *? \]

Das Match ist [more or less]. Ich muss nur bekommen more or less(ohne die Klammern).

Ist es möglich das zu tun?


Antworten:


453

Einfach gemacht:

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

Technisch gesehen werden dazu Lookaheads und Lookbehinds verwendet. Siehe Lookahead und Lookbehind Zero-Width Assertions . Das Muster besteht aus:

  • geht ein [voraus, das nicht erfasst wird (lookbehind);
  • eine nicht gierige gefangene Gruppe. Es ist nicht gierig, beim ersten Mal anzuhalten]; und
  • wird von einem] gefolgt, das nicht erfasst wird (Lookahead).

Alternativ können Sie einfach erfassen, was sich zwischen den eckigen Klammern befindet:

\[(.*?)\]

und geben Sie die erste erfasste Gruppe anstelle des gesamten Spiels zurück.


138
"Einfach gemacht", LOL! :) Reguläre Ausdrücke bereiten mir immer Kopfschmerzen, ich neige dazu, sie zu vergessen, sobald ich diejenigen finde, die meine Probleme lösen. Über Ihre Lösungen: Die erste funktioniert wie erwartet, die zweite nicht, sie enthält weiterhin die Klammern. Ich verwende C #, vielleicht hat das RegEx-Objekt seinen eigenen "Geschmack" der Regex-Engine ...
Diego

5
Das geschieht, weil Sie eher das gesamte Spiel als die erste übereinstimmende Gruppe betrachten.
Cletus

Vielen Dank, sehr nützliche Website! Ich werde es als Referenz behalten. :) Entschuldigung, wenn ich etwas Verwirrung
Diego

1
Funktioniert dies, wenn der Teilstring auch die Trennzeichen enthält? Zum Beispiel in This is a test string [more [or] less]würde dies zurückkehren more [or] less?
Gnzlbg

1
@gnzlbg nein, es würde "mehr [oder" zurückgeben
MerickOWA

52

Wenn Sie JavaScript verwenden , funktioniert die erste von cletus bereitgestellte Lösung(?<=\[)(.*?)(?=\]) nicht, da JavaScript den Lookbehind-Operator nicht unterstützt.

Die zweite Lösung funktioniert zwar gut, Sie müssen jedoch das zweite übereinstimmende Element erhalten.

Beispiel:

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

Es wird zurückkehren:

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

Was Sie also brauchen, ist der zweite Wert. Verwenden:

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

Zurückgeben:

"more or less"

2
Was ist, wenn die Zeichenfolge mehrere Übereinstimmungen von [mehr oder weniger] enthält?

Lookbehind-Zusicherungen wurden zu RegExp in ES2018
TheDarkIn1978

19

Sie müssen nur das Bit zwischen den Klammern 'erfassen'.

\[(.*?)\]

Zum Erfassen setzen Sie es in Klammern. Sie sagen nicht, welche Sprache dies verwendet. In Perl würden Sie beispielsweise mit der Variablen $ 1 darauf zugreifen.

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

Andere Sprachen haben andere Mechanismen. Ich glaube, C # verwendet zum Beispiel die Match-Auflistungsklasse .


Vielen Dank, aber diese Lösung hat nicht funktioniert. Sie enthält weiterhin eckige Klammern. Wie ich in meinem Kommentar zu Cletus 'Lösung geschrieben habe, könnte es sein, dass das C # RegEx-Objekt es anders interpretiert. Ich bin kein Experte für C #, also ist es nur eine Vermutung, vielleicht ist es nur mein Mangel an Wissen. :)
Diego

11

[^\[] Entspricht jedem Zeichen, das nicht [.

+Match 1 oder mehr von allem, was nicht ist [. Erstellt Gruppen dieser Übereinstimmungen.

(?=\])Positiver Lookahead ]. Entspricht einer Gruppe, die mit endet, ]ohne sie in das Ergebnis aufzunehmen.

Getan.

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

Beweis.

http://regexr.com/3gobr

Ähnlich der von null vorgeschlagenen Lösung. Das zusätzliche \]ist aber nicht erforderlich. Als zusätzliche Anmerkung scheint \es nicht erforderlich zu sein, die [nach dem zu entkommen ^. Zur besseren Lesbarkeit würde ich es belassen.

Funktioniert nicht in Situationen, in denen die Trennzeichen identisch sind. "more or less"beispielsweise.


8

PHP:

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


3

Ich hatte das gleiche Problem mit Regex mit Bash-Skripten. Ich habe eine 2-Schritt-Lösung mit Rohren mit grep -o verwendet

 '\[(.*?)\]'  

Zuerst, dann

'\b.*\b'

Offensichtlich nicht so effizient bei den anderen Antworten, aber eine Alternative.


3

Dieser funktioniert speziell für den Parser für reguläre Ausdrücke von Javascript /[^[\]]+(?=])/g

Führen Sie dies einfach in der Konsole aus

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

2

Ich wollte eine Zeichenfolge zwischen / und # finden, aber # ist manchmal optional. Hier ist die Regex, die ich benutze:

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

0

Hier ist, wie ich ohne '[' und ']' in C # gekommen bin:

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

Die Ausgabe ist:

more or less

-1

Wenn Sie den Text ohne Klammern extrahieren müssen, können Sie bash awk verwenden

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

Ergebnis:

hola mundo

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.