Regex работает в поиске / замене VS Code, но не в сценарии sed - PullRequest
1 голос
/ 18 июня 2020

Я понимаю, что этот вопрос уже задавали 100 раз на Stack Overflow. Несмотря на чтение множества вопросов и ответов, я все еще застрял.

Начало: https://website.com/page.html?q=term,tag-one,tag-two,tag-three,15

Цель: https://website.com/page.html,tag-one,tag-two,tag-three,15

Изменить: term представляет любую строка, включая что-то вроде search% 20term

Это успешно работает в поиске / замене VS Code:

Search: \?.*?,

Replace: ,

Однако при использовании в сценарии Bash это: sed -E 's|\?.*?,|,|'

Результат: https://website.com/page.html,15

Как ни удивительно, но это работает: sed -E 's|#.*?,|,|'

Я думал, что:

  • s означает замену
  • экранирование \? сообщает команде найти буквальные вопросительные знаки
  • .*?, указывает команде захватить любой символ до тех пор, пока первая запятая не дойдет до
  • g не требуется в команде
  • -E позволяет sed распознавать больше регулярных выражений, чем -e

Это мое основное c понимание непрофессионала и, вероятно, ошибочное.

Может ли кто-нибудь рассказать мне, что происходит? Спасибо, если да.

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Соответствует любому символу, кроме , (запятая)

Проблема, с которой вы столкнулись, кажется, возникает из-за того, что подстановочный знак * соответствует любому символу и впоследствии будет соответствовать всем , (запятые), пока не останется только один (который соответствует , в вашем регулярном выражении).

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

sed -E 's|\?[^,]*,|,|'
1 голос
/ 18 июня 2020

Ваши предположения верны:

  • s означает замену
  • экранирование \? сообщает команде найти буквальные вопросительные знаки
  • .*?, сообщает команда для захвата любого символа до первой запятой, но не жадная в отличие от .*
  • g не требуется в команде
  • -E позволяет sed распознавать больше регулярных выражений, чем -e, расширенное регулярное выражение

Вот так:

sed -E 's|\?[^,]+,|,|'
  • [^,] означает все, но не , и + означает хотя бы одно вхождение

Или используя интуитивно понятный уже работоспособный решение, которое вы сделали в VS Code, но теперь в Perl:

perl -pe 's|\?.*?,|,|'

Что происходит, так это то, что не жадное универсальное регулярное выражение .*? не распознается sed. Но perl поймите.

Вывод

Start: https://website.com/page.html,tag-one,tag-two,tag-three,15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...