вопрос о регулярных выражениях в Vim - PullRequest
4 голосов
/ 06 сентября 2010

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

echo '* text is here' =~ '\^*\*\s'  prints 1 (i.e., MATCH)
echo '* text is here' =~ '^*\*\s'   prints 0 (NO MATCH)

echo '** text is here' =~ '\^*\*\s' (MATCH)
echo '** text is here' =~ '^*\*\s'  (MATCH)

echo '*** text is here' =~ '\^*\*\s' (MATCH)
echo '*** text is here' =~ '^*\*\s'  (NO MATCH)

echo 'text is here' =~ '\^*\*\s' (NO MATCH)
echo 'text is here' =~ '^*\*\s'  (NO MATCH)

echo '*text is here' =~ '\^*\*\s' (NO MATCH)
echo '*text is here' =~ '^*\*\s'  (NO MATCH)

Из этих результатов я понимаю, что когда символ начала строки (^) равен , а не с добавлением обратной косой черты, следующее * читается каклитерал и обратный слеш_ * также читается как литерал.Таким образом, результат при сравнении с использованием метода no-initial-backslash соответствует только строке с ровно двумя звездочками, за которыми следует пробел.

Когда перед символом ^ стоит обратный слеш, первая звездочка - это буквальная звездочка, а обратная косая черта- * означает «ноль или более предшествующего символа».

Версия с начальной обратной косой чертой дает мне ответы, которые я хочу;т. е. он совпадает со строками «все и только», начинающимися с одной или нескольких звездочек, за которыми следует пробел.Почему это?Когда я смотрю на документацию Vim, там говорится, что \ ^ обозначает литерал ^, а не начало строки.Я уверен, что есть простое объяснение, но я не вижу его.Спасибо за любые разъяснения.

Я также замечаю некоторое похожее поведение при наборе этого вопроса.Таким образом, следующая строка имеет обратную косую черту перед второй звездочкой, которая не отображается в тексте: '^ ** \ s'.

ОБНОВЛЕНИЕ: Хорошо, я думаю, что у меня получился ответ Росса 'и вижу, что снятие якоря дало мне желаемый результат.Отмена привязки также дает мне результат, которого я не хочу, а именно:

echo 'text* is here' =~ '\^*\*\s' (MATCH)

ТАК, МОЙ ВОПРОС СЕЙЧАС ЕСТЬ: какое регулярное выражение будет совпадать со строками "все и только", которые начинаются с одной или нескольких звездочекс последующим пробелом?Приведенное ниже регулярное выражение сближается, но в последнем примере происходит сбой:

echo '*** text is here' =~ '^**\s' (MATCH)
echo '* text is here' =~ '^**\s' (MATCH)
echo 'text* is here' =~ '^**\s' (NO MATCH)
echo ' * text is here' =~ '^**\s' (MATCH) -- want a no match here

Версия с косой чертой в качестве первой звездочки также не работает (например, '^ \ ** \ s').

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ: Хорошо, я думаю, что нашел версию, которая работает.Я точно не понимаю, почему это работает.Похоже, что я ожидал бы, за исключением звездочки после символа ^, но наличие повторителя после ^ кажется бессмысленным:

echo '*** text is here' =~ '^*\**\s' (MATCH)
echo '* text is here' =~ '^*\**\s'   (MATCH)
echo 'text* is here' =~ '^*\**\s'   (NO MATCH)
echo ' * text is here' =~ '^*\**\s' (NO MATCH)

Ответы [ 3 ]

4 голосов
/ 06 сентября 2010

Ааа, интересное объяснение, но не совсем правильное.

\^ действительно относится к буквальному круговому сгибанию.

Но * не означает " один или более", это означает " ноль или более", поэтому \^* просто ничего не соответствует, если это необходимо для того, чтобы чтобы сделать оставшееся выражение успешным, и, кроме того, оно, очевидно, будет «декантировать» оставшуюся часть поиска, упрощая его.

Я полагаю, что с этой частью головоломки у вас не возникнет проблем с пониманием всего остального ...

Обновление : я думаю, что последняя часть головоломки состоит в том, что vi делает что-то немного другое с магическими персонажами регулярных выражений вне контекста. Если вы используете один в контексте, где он не может быть магическим, вы не получите ошибку, как с Perl или Ruby, персонаж просто станет немагичным. И * не повторяет привязку ^, поэтому при поиске, например /*/ или /^*/, будет искать любой фактический * или строку, начинающуюся с фактического *, соответственно.

2 голосов
/ 06 сентября 2010

Почему бы просто не использовать: '^\*\+'?Это будет соответствовать одной или нескольким звездочкам в начале строки в VIM.

2 голосов
/ 06 сентября 2010

'\^*\*\s' соответствует, поскольку первая звездочка обозначает ноль или более ^ (в данном случае ноль), а затем следующий литерал * соответствует первому вхождению.

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