Регулярное выражение, чтобы найти строку, включенную между двумя символами при ИСКЛЮЧЕНИИ разделителей


295

Мне нужно извлечь из строки набор символов, которые находятся между двумя разделителями, не возвращая сами разделители.

Простой пример должен быть полезен:

Цель : извлечь подстроку в квадратных скобках, не возвращая сами скобки.

Базовая строка :This is a test string [more or less]

Если я использую следующие рег. ех.

\ [. *? \]

Матч есть [more or less]. Мне нужно только получить more or less(без скобок).

Возможно ли это сделать?


Ответы:


454

Легко сделано:

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

Технически это использует lookaheads и lookbehinds. Смотрите Lookahead и Lookbehind Утверждения нулевой ширины . Шаблон состоит из:

  • предшествует [который не захвачен (взгляд сзади);
  • не жадная захваченная группа. Нежадно останавливаться сначала]; и
  • сопровождается], который не захвачен (взгляд вперед).

В качестве альтернативы вы можете просто взять то, что находится в квадратных скобках:

\[(.*?)\]

и вернуть первую захваченную группу вместо всего совпадения.


138
"Легко сделано", LOL! :) Регулярные выражения всегда вызывают у меня головную боль, я склонен их забывать, как только найду те, которые решают мои проблемы. О ваших решениях: первое работает как положено, второе - нет, оно включает в себя скобки. Я использую C #, возможно, у объекта RegEx есть свой «вкус» движка регулярных выражений ...
Диего

5
Это происходит потому, что вы смотрите на весь матч, а не на первую подобранную группу.
Клет

Большое спасибо, очень полезный сайт! Я буду держать это в качестве ссылки. :) Извините, если я сделал некоторую путаницу, разработка C # на самом деле не является одним из моих навыков ..
Диего

1
Это работает, если подстрока также содержит разделители? Например, This is a test string [more [or] less]будет ли это возвращение more [or] less?
gnzlbg

1
@gnzlbg нет, будет возвращено «больше [или»
MerickOWA

53

Если вы используете JavaScript , первое решение, предоставленное cletus, (?<=\[)(.*?)(?=\])не будет работать, потому что JavaScript не поддерживает оператор lookbehind.

Однако второе решение работает хорошо, но вам нужно получить второй соответствующий элемент.

Пример:

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

Он вернется:

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

Итак, что вам нужно, это второе значение. Использование:

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

Возвращаться:

"more or less"

2
Что делать, если в строке несколько совпадений [больше или меньше]?


19

Вам просто нужно «захватить» бит между скобками.

\[(.*?)\]

Для захвата вы положите его в скобки. Вы не говорите, на каком языке это используется. Например, в Perl вы могли бы получить к нему доступ, используя переменную $ 1.

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

Другие языки будут иметь разные механизмы. Например, в C # используется класс коллекции Match .


Спасибо, но это решение не сработало, оно содержит квадратные скобки. Как я написал в своем комментарии к решению Cletus, возможно, объект C # RegEx интерпретирует его по-разному. Я не эксперт по C #, так что это всего лишь предположение, может быть, это просто мое отсутствие знаний. :)
Диего

11

[^\[] Подберите любой символ, который не [.

+Совпадение 1 или более из всего, что не является [. Создает группы из этих матчей.

(?=\])Позитивный взгляд ]. Совпадает с группой, заканчивающейся ]без включения ее в результат.

Готово.

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

Доказательство.

http://regexr.com/3gobr

Аналогично решению, предложенному null. Но дополнительного \]не требуется. В качестве дополнительного примечания, по-видимому \, не требуется экранировать [после ^. Для удобства чтения я бы оставил это в.

Не работает в ситуации, в которой разделители идентичны. "more or less"например.


8

PHP:

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


3

У меня была та же проблема с использованием регулярных выражений с сценариями Bash. Я использовал двухэтапное решение, используя трубы с применением grep -o

 '\[(.*?)\]'  

будет первый

'\b.*\b'

Очевидно, не так эффективно, как другие ответы, но альтернатива.


3

Это специально работает для синтаксического анализатора регулярных выражений JavaScript /[^[\]]+(?=])/g

просто запустите это в консоли

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

2

Я хотел найти строку между / и #, но # иногда необязательно. Вот регулярное выражение, которое я использую:

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

0

Вот как я получил без '[' и ']' в 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]);
        }

Выход:

more or less

-1

Если вам нужно извлечь текст без скобок, вы можете использовать bash awk

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

результат:

hola mundo

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.