Gnu sed: вывести (и) в regex

Я заметил несколько сообщений на этом сайте, которые говорят, что с помощью gnu sed вы должны использовать ( и ) в регулярном выражении, а не \( и \). Но затем я посмотрел в gnu sed manual и увидел, что они указывают, что должны использоваться \( и \). Что?

Ответы

Ответ 1

Благодаря рокеру, мургам и крису. Каждый из вас помог мне понять эту проблему. Я отвечаю на свой вопрос здесь, чтобы (надеюсь) объединить всю историю в одном месте.

Существуют две основные версии sed: gnu и bsd. Оба из них требуют, чтобы parens в базовом регулярном выражении были экранированы при использовании для группировки, но не экранировались при использовании в расширенном регулярном выражении. Они отличаются тем, что опция -r позволяет расширенное регулярное выражение для gnu, но -E делает это для bsd.

Стандартным sed в mac OSX является bsd. Я считаю, что большая часть остального мира использует gnu sed как стандарт, но я точно не знаю, кто использует что. Если вы не уверены, что используете, попробуйте:

> sed -r

Если вы получите

> sed: illegal option -- r

ответ, тогда у вас есть bsd.

Ответ 2

Эта часть руководства gnu sed, с которым вы связаны, объясняет, следует ли вам избегать скобок, зависит от того, используете ли вы основные регулярные выражения или расширенные обычные выражения. В этой части говорится, что флаг -r определяет, в каком режиме вы находитесь.

Изменить:, как указано в комментарии grok12, флаг -E в bsd sed делает то, что делает флаг -r в gnu sed.

Ответ 3

Первоначально sed, как и grep, и все остальное, использовали\(чтобы указать группировку, тогда как (просто совпадал с литералом open-paren.

Множество новых реализаций регулярных выражений, включая egrep и perl, переключилось так, так что\(означало буквальный open-paren и (использовался для указания группировки.

Итак, теперь с gnu sed (является особым символом, как, например, egrep). Но в других системах (например, BSD) это все еще старый способ, насколько я могу судить. К сожалению, это настоящий беспорядок, потому что теперь он трудно узнать, какой из них использовать.

Ответ 4

Скопированные скобки (\() делают поиск регулярных выражений круглыми скобками как часть выражения.

Необязательные круглые скобки (() объединяют содержимое регулярных выражений в круглые скобки.

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

Пример для демонстрации:

$myString = "junk(150)moar";

Чтобы получить только номер:
#^\w+\((\d+)\)\w+$#

($1 is 150)

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

Обновление лет спустя:

Как указывает пользователь @bmk, этот ответ применяется к расширенным регулярным выражениям, но не к основным регулярным выражениям. Трудно найти основные регулярные выражения в качестве механизма синтаксического анализа по умолчанию на большинстве языков программирования и т.д., Но было бы разумно проверить, какой движок вы используете, прежде чем считать, что этот ответ будет применим к вашей ситуации.