Обратный порядок приоритетов соответствия шаблонам в sed / regexes

Рассмотрим эту команду:

echo "string.with.dots" | sed 's/\(.*\)\.\(.*\)/\1\n\2/'

(Соответствует первой группе захвата любого символа до последнего . и второй группе захвата любого символа после него.)

Это Результаты:

string.with
dots

Разумно (я думаю) Я подумал, что использование якорей в правильной комбинации могло бы изменить такое поведение (то есть совпадение было бы string для первой группы захвата и with.dots ] для второй группы захвата), но:

echo "string.with.dots" | sed 's/^\(.*\)\.\(.*\)/\1\n\2/'
echo "string.with.dots" | sed 's/^\(.*\)\.\(.*\)$/\1\n\2/'
echo "string.with.dots" | sed 's/\(.*\)\.\(.*\)$/\1\n\2/'

Весь вывод:

string.with
dots

Я не знаю, как реализовано сопоставление с образцом, но кажется, что это всегда привилегии шаблоны ближе к началу строки, а не ближе к концу строки (несмотря на наличие ^ или отсутствие $).

Как можно изменить это поведение (т. Е. Не как написать жестко закодированное решение для этого примера, а как обратить порядок приоритетов сопоставления с образцом в sed или в регулярные выражения в целом) если возможно?

5
задан 8 April 2015 в 06:24

3 ответа

Добавьте два rev и подкачайте \1 и \2:

echo "string.with.dots" | rev | sed 's/\(.*\)\.\(.*\)/\2\n\1/' | rev

Вывод:

string
with.dots
3
ответ дан 8 April 2015 в 06:24

Интересно, можно ли сойти с рук использование удара расширение параметра

$ s="string.with.dots"
$ echo "${s%%.*}"; echo "${s#*.}"
string
with.dots
$ echo "${s%.*}"; echo "${s##*.}"
string.with
dots
1
ответ дан 8 April 2015 в 06:24

Для получения, что Вы хотите, пробуют это:

sed -r 's/^([^.]*)\.(.*)/\1\n\2/'

Тест:

$ echo "string.with.dots" | sed -r 's/^([^.]*)\.(.*)/\1\n\2/'
string
with.dots

sed будет соответствовать жадно, поэтому в то время как Вы используете sed 's/\(.*\)\.\(.*\)/\1\n\2/' это будет жадно соответствовать до в последний раз . как первая полученная группа и затем затем остальные после . как второй.

В моем sed выражение, для остановки sed от того, чтобы быть жадным, я должен искать некоторые альтернативы. Я соответствовал от запуска до a . как первая группа ([^.]*) и затем безотносительно после первого соответствия как второе.

Теперь, если Вы хотите все части вокруг . в отдельных строках:

$ echo "string.with.dots" | sed -r 's/^([^.]*)\.([^.]*)\.(.*)/\1\n\2\n\3/'
string
with
dots
3
ответ дан 8 April 2015 в 06:24

Другие вопросы по тегам:

Похожие вопросы: