2009-09-21 3 views
178

Мне нужно извлечь из строки набор символов, которые включены между двумя разделителями, не возвращая сами разделители.Регулярное выражение, чтобы найти строку, содержащуюся между двумя символами, в то время как ИСКЛЮЧАЯ разделители

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

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

Базовая строка: Это тестовая строка [более или менее]

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

\[.*?\]

Игра [больше или меньше]. Мне нужно получить только более или менее (без скобок).

Возможно ли это?

+0

Связано: [Regex Совместить все символы между двумя строками] (https://stackoverflow.com/q/6109882) – Dukeling

ответ

289

делается легко:

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

Технически это использует lookaheads и просмотра назад. См. Lookahead and Lookbehind Zero-Width Assertions. Образец состоит из:

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

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

\[(.*?)\] 

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

+79

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

+2

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

+0

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

17

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

\[(.*?)\] 

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

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

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

+0

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

+0

Извините, я не имел ввиду, чтобы ответить на этот вопрос! – im3r3k

7

PHP:

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

Для удаления также использовать []:

\[.+\] 
0

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

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

результат:

hola mundo

2

У меня была такая же проблема с использованием regex с bash-скриптами. я использовал 2-ступенчатое решение с использованием труб с применением Grep -o

'\[(.*?)\]' 

, а затем

'\b.*\b' 

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

19

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

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

Пример:

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

Классический трюк-чувак –

2

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

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

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

[^\[] любой символ это не [.

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

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

Выполнено.

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

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

http://regexr.com/3gobr

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

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

Смежные вопросы