регулярное выражение ack: сопоставление двух слов по порядку в одной строке

#regex #ack

#регулярное выражение #подтверждение

Вопрос:

Я хотел бы найти строки в файлах, которые содержат два слова, word_1 и word_2 по порядку, как в Line A приведенном ниже, но не как в Line B или Line C :

 Line A: ... word_1 .... word_2 .... 
Line B: ... word_1 ....
Line C: ... word_2 ....
  

Я пытался

 $ack '*word_1*word_2'
$ack '(word_1) *(word_2) '
  

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

Ни одна из этих команд не возвращает файлы или строки, которые меня интересуют.

Что я делаю не так?

Спасибо!

Ответ №1:

Вы хотите найти word_1 , за которым следует что угодно, любое количество раз, за которым следует word_2 . Это должно быть

 word_1.*word_2
  

Кажется, вы используете * так, как это часто используется при поиске в командной строке, но в регулярных выражениях это квантор для предыдущего символа, то есть сопоставьте его не менее 0 раз. Например, регулярное выражение a* будет соответствовать 0 или более a секундам, тогда как регулярное выражение a будет соответствовать хотя бы одному a .

Метасимвол регулярного выражения, означающий «сопоставлять что угодно», является . , so .* означает «сопоставлять что угодно любое количество раз. Смотрите perlrequick для краткого введения по теме.

Комментарии:

1. Спасибо @dsolimano! Будет ли какая-либо разница между тем, что вы написали, и: .*word_1.*word_2 . Если нет, то почему?

2. Вроде того, но не для того, на что вы смотрите. Это дополнительно соответствовало бы всему, что было до word_1 в строке. Если бы вы смотрели на то, что соответствует, а не на то, совпадает это или нет, вы бы увидели больше информации в совпадении. Если у вас есть немного денег и времени, я бы рекомендовал прочитать «Освоение регулярных выражений» Фридла, это превосходно.