Выделите текст, который соответствует регулярному выражению - PullRequest
1 голос
/ 16 апреля 2020

Когда я использую ag или rg для выделения текста, он выделяет выделенный текст.

$ echo "First HTML appeared, then CSS, then JavaScript" | rg -N 'HTML|php|CSS|Java(Script)?' 
$ echo "First HTML appeared, then CSS, then JavaScript" | ag --nonumbers 'HTML|php|CSS|Java(Script)?'

Но когда я использую Perl, он не выделяет соответствующий текст.

$ echo "First HTML appeared, then CSS, then JavaScript" | perl -ne '/HTML|php|CSS|Java(Script)?/ and print'

enter image description here

Я попробовал следующее:

echo "First HTML appeared, then CSS, then JavaScript" | perl -ne 'use Term::ANSIColor qw(:constants);/HTML|php|CSS|Java(Script)?/ and print RED, $_'

echo "First HTML appeared, then CSS, then JavaScript" | perl -ne 'use Term::ANSIColor;/HTML|php|CSS|Java(Script)?/ and print color("red"), $_'

Изменяет цвет всего текста, а не выделенного текста .

Как выделить текст, соответствующий регулярному выражению при использовании Perl для поиска?

Ответы [ 3 ]

3 голосов
/ 16 апреля 2020

Боюсь, будет не так просто закрасить слово или несколько слов в строке большим количеством текста. Хороший модуль окрашивает данную ему строку и не может выбрать части из этого, насколько я знаю.

Так что это должно быть сделано от руки, слово (через пробел) за словом, и это немного грязно. Например,

echo "First HTML appeared, then CSS, then JavaScript" |
perl -MTerm::ANSIColor=:constants -wne'
    @p = split /([,.\-\s+])/;  
    for (@p) { /HTML|php|CSS|Java(Script)?/ ? print RED $_, RESET : print }'

Эта демонстрация корректно работает с данной строкой, но я уверен, что можно найти случаи, которые ее сломают, учитывая, что она анализирует строку в этом split, что не является простое дело вообще.

Захват () в шаблоне разделителя в split делает так, чтобы эти разделители также возвращались в списке результатов, чтобы мы могли восстановить текст со всем, что у него было. Я включаю там некоторые знаки препинания, вместе с пробелами, но это то, на что нужно внимательно смотреть и расширять по мере необходимости.

Этой "игры синтаксического анализа" можно избежать, разбив шаблон регулярных выражений на нужные слова

perl -MTerm::ANSIColor=:constants -wne'
    BEGIN { $re = qr/HTML|php|CSS|Java(?:Script)?/ };
    for (split /($re)/) { /$re/ ? print RED $_, RESET : print }'

Регулярное выражение сначала сохраняется в переменной, чтобы избежать глупого повторения возможно ужасного выражения

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


Ну, это так - вставьте подходящие экранирования ANSI, используя регулярные выражения. Смотрите другие ответы здесь для этого подхода

2 голосов
/ 16 апреля 2020

Вы переключаете цвет на красный, печатаете всю строку, а затем оставляете красный цвет. Ничего хорошего.

Вы хотите напечатать несоответствующий текст, переключите цвет на красный, напечатать соответствующий текст, сбросьте цвет и повторите при необходимости.

С RED и RESET просто возвращайте строки, которые интерпретируются терминалом, мы могли бы достичь желаемого эффекта, вставив эти строки в соответствующие места строки для печати, заменив

/HTML|php|CSS|Java(Script)?/ and print RED, $_

на

s/HTML|php|CSS|Java(?:Script)?/RED.$&.RESET/eg; print

Мы можем написать команду оболочки следующим образом:

perl -MTerm::ANSIColor=RED,RESET -pe's/HTML|php|CSS|Java(?:Script)?/RED.$&.RESET/eg'

Мы можем удалить зависимость следующим образом:

perl -pe'
   BEGIN { $RED="\e[31m"; $RESET="\e[0m" }
   s/HTML|php|CSS|Java(?:Script)?/$RED$&RESET/g
'

(разрывы строк могут быть оставлены или удалены.)

Мы могли бы даже встроить строки за счет читабельности, удобства обслуживания и т. Д. c.

perl -pe's/HTML|php|CSS|Java(?:Script)?/\e[31m$&\e[0m/g'
1 голос
/ 16 апреля 2020

Благодаря @PolarBear для меня работает решение:

echo "First HTML appeared, then CSS, then JavaScript" | perl -pe 's/(HTML|php|CSS|Java(Script)?)/\e[31m\e[1m\e[4m$1\e[0m/g'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...