Параметр приоритета обратного упорядочения / регулярных выражений

5

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

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

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

Выводится:

string.with
dots

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

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

Весь вывод:

string.with
dots

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

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

    
задан kos 06.04.2015 в 22:36
источник

3 ответа

1

Добавьте два rev и swap и :

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

Вывод:

string
with.dots
    
ответ дан Cyrus 06.04.2015 в 23:03
источник
3

Чтобы получить то, что вы хотите, попробуйте это:

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

Тест:

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

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

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

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

$ echo "string.with.dots" | sed -r 's/^([^.]*)\.([^.]*)\.(.*)/\n\n/'
string
with
dots
    
ответ дан heemayl 06.04.2015 в 22:43
1

Интересно, можете ли вы избежать использования bash расширения параметра

$ s="string.with.dots"
$ echo "${s%%.*}"; echo "${s#*.}"
string
with.dots
$ echo "${s%.*}"; echo "${s##*.}"
string.with
dots
    
ответ дан glenn jackman 06.04.2015 в 23:26