Wyrażenie regularne, aby znaleźć ciąg znaków zawarty między dwoma znakami z WYŁĄCZENIEM ograniczników


294

Muszę wyodrębnić z łańcucha zestaw znaków, które są zawarte między dwoma ogranicznikami, bez zwracania samych ograniczników.

Prosty przykład powinien być pomocny:

Cel : wyodrębnij podciąg między nawiasami kwadratowymi, bez zwracania samych nawiasów.

Ciąg podstawowy :This is a test string [more or less]

Jeśli użyję następującego reg. dawny.

\ [. *? \]

Mecz jest [more or less]. Muszę tylko dostać more or less(bez nawiasów).

Czy można to zrobić?


Odpowiedzi:


453

Łatwo zrobione:

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

Technicznie używa to lookaheads i lookbehinds. Patrz : Twierdzenia Lookahead i Lookbehind o zerowej szerokości . Wzór składa się z:

  • poprzedza [, który nie jest przechwytywany (patrz niżej);
  • schwytana grupa, która nie jest chciwa. Nie jest chciwy zatrzymać się na początku]; i
  • po nim następuje], który nie jest przechwytywany (patrz przed siebie).

Alternatywnie możesz po prostu uchwycić to, co jest w nawiasach kwadratowych:

\[(.*?)\]

i zwróć pierwszą przechwyconą grupę zamiast całego meczu.


138
„Łatwo gotowe”, LOL! :) Wyrażenia regularne zawsze powodują ból głowy, zwykle zapominam o nich, gdy tylko znajduję te, które rozwiązują moje problemy. O twoich rozwiązaniach: pierwsze działa zgodnie z oczekiwaniami, drugie nie, nadal zawiera nawiasy klamrowe. Używam C #, może obiekt RegEx ma swój własny „smak” silnika regex ...
Diego

5
Robi to, ponieważ patrzysz na cały mecz, a nie na pierwszą dopasowaną grupę.
cletus

Wielkie dzięki, bardzo przydatna strona internetowa! Zachowam to jako punkt odniesienia. :) Przepraszam, jeśli się pomyliłem, rozwój C # nie jest tak naprawdę jedną z moich umiejętności ..
Diego

1
Czy to działa, jeśli podciąg zawiera również ograniczniki? Na przykład, This is a test string [more [or] less]czy ten zwrot miałby powrócić more [or] less?
gnzlbg

1
@gnzlbg nie, zwróci „więcej [lub”
MerickOWA,

52

Jeśli używasz JavaScript , pierwszego rozwiązania dostarczonego przez cletus, (?<=\[)(.*?)(?=\])nie będzie działać, ponieważ JavaScript nie obsługuje operatora lookbehind.

Jednak drugie rozwiązanie działa dobrze, ale musisz uzyskać drugi dopasowany element.

Przykład:

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

Zwróci:

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

Zatem potrzebna jest druga wartość. Posługiwać się:

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

Wracać:

"more or less"

2
co jeśli w ciągu jest wiele dopasowań [więcej lub mniej]?

Twierdzenia Lookbehind
TheDarkIn1978

19

Musisz tylko „uchwycić” bit między nawiasami.

\[(.*?)\]

Aby to zrobić, umieść go w nawiasach. Nie mówisz, jakiego języka używa. Na przykład w Perlu można uzyskać do niego dostęp za pomocą zmiennej $ 1.

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

Inne języki będą miały różne mechanizmy. Na przykład C # wykorzystuje klasę kolekcji Match , jak sądzę.


Dzięki, ale to rozwiązanie nie działało, nadal zawiera nawiasy kwadratowe. Jak napisałem w moim komentarzu do rozwiązania Cletus, możliwe, że obiekt C # RegEx interpretuje to inaczej. Nie jestem jednak ekspertem w języku C #, więc to tylko przypuszczenie, może to tylko mój brak wiedzy. :)
Diego

11

[^\[] Dopasuj dowolny znak, który nie jest [.

+Dopasuj 1 lub więcej elementów, które nie są [. Tworzy grupy tych dopasowań.

(?=\])Pozytywne spojrzenie w przyszłość ]. Dopasowuje grupę kończącą się ]bez uwzględnienia jej w wyniku.

Gotowy.

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

Dowód.

http://regexr.com/3gobr

Podobne do rozwiązania zaproponowanego przez null. Ale dodatkowe \]nie jest wymagane. Jako dodatkową uwagę, wydaje się, że \nie jest wymagane ucieczka [po^ . Dla czytelności pozostawiłbym to.

Nie działa w sytuacji, w której ograniczniki są identyczne. "more or less"na przykład.


8

PHP:

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


3

Miałem ten sam problem przy użyciu wyrażenia regularnego z skryptami bash. Użyłem 2-etapowego rozwiązania przy użyciu rur z aplikacją grep -o

 '\[(.*?)\]'  

więc najpierw

'\b.*\b'

Oczywiście przy innych odpowiedziach nie jest tak skuteczny, ale alternatywa.


3

Ten konkretnie działa dla parsera wyrażeń regularnych javascript /[^[\]]+(?=])/g

po prostu uruchom to w konsoli

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

2

Chciałem znaleźć ciąg między / i #, ale # jest czasami opcjonalny. Oto regex, którego używam:

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

0

Oto jak udało mi się bez „[” i „]” w 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]);
        }

Dane wyjściowe to:

more or less

-1

Jeśli potrzebujesz wyodrębnić tekst bez nawiasów, możesz użyć bash awk

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

wynik:

hola mundo

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.