Intereting Posts
Как установить WINE в RHEL 6.3? Как идентифицировать и удалить пакеты, которые больше не используются? Компиляция GNU Octave не выполняется с помощью libinterp / .libs / liboctinterp.so: неопределенная ссылка на `Magick :: * pthread в реальном времени, созданный из потока, отличного от реального времени, с помощью init.d Отключить проверку почты при входе в систему? Как использовать устройство Peak PCAN-USB для сохранения CAN-трассировки с использованием модулей ядра 4.4? Как удалить текст с начала каждой строки и вставить его в конец каждой строки в терминале Как прыгать на позицию, указанную строкой и столбцом? Как настроить собственный EDID вручную? Переименовать USB Sound device Почему моя команда systemctl v208 не поддерживает некоторые функции? Может ли касификация case bash? вырезать столбец 2 из текстового файла / root / bin / ffmpeg: ошибка при загрузке разделяемых библиотек: libtheoraenc.so.1: невозможно открыть файл общих объектов: нет такого файла или каталога Головной сервер Debian + Клиенты Windows + Экспедирование X11

Как использовать + в регулярном выражении в sed?

Я нахожусь в Windows, но, наверное, мой вопрос по-прежнему справедливо размещен здесь.

C:\Users\User>grep --version GNU grep 2.6.3 C:\Users\User>sed --version GNU sed version 4.2.1 

Я заметил, что следующие работы (вывод here ):

 echo here | grep -E "\w+" echo here | grep -E "[her]+" 

Но это не работает (ничего не выводит):

 echo here | grep -E "[\w]+" 

Это снова делает (вывод here ):

 echo here | grep -P "[\w]+" 

Таким образом, [\w] является чем-то специфичным для регулярных выражений Perl, я полагаю. Это верно?

Итак, давайте поговорим sed . Это работает (вывод gone ):

 echo here | sed -r "s/\w+/gone/" echo here | sed -r "s/[her]+/gone/" 

И снова это не выводится here :

 echo here | sed -r "s/[\w]+/gone/" 

Теперь, как я могу активировать регулярные выражения Perl для sed – есть ли способ?

Различные инструменты и версии поддерживают различные варианты регулярных выражений. Документация каждого из них расскажет вам, что они поддерживают.

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

Например, все современные реализации sed и grep реализуют базовые регулярные выражения, как указано POSIX (по крайней мере, одна версия или другая стандартная версия, но этот стандарт в последние несколько десятилетий не сильно изменился).

В POSIX BRE и ERE у вас есть класс символов [:alnum:] . Это соответствует буквам и цифрам в вашей локали (обратите внимание, что часто включает в себя намного больше, чем a-zA-Z0-9 если локаль не является C).

Так:

 grep -x '[[:alnum:]_]\{1,\}' 

соответствует одному или нескольким alnums или _.

[\w] требуется POSIX для соответствия либо обратной косой чертой, либо w . Таким образом, вы не найдете реализацию grep или sed где это доступно (если не через нестандартные параметры).

Поведение только для \w не указывается POSIX, поэтому реализациям разрешено делать то, что они хотят. GNU grep добавил, что давным-давно.

GNU grep использовал свой собственный движок regexp, но теперь он использует GNU libc (хотя он и вставляет свою собственную копию).

Он предназначен для соответствия alnums и подчеркивания в вашем языке. Тем не менее, в настоящее время он имеет ошибку в том, что он соответствует только однобайтным символам (например, не é в локали UTF-8, хотя это явно письмо и даже если оно соответствует é во всех локалях, где é является одиночным персонаж).

Также существует оператор \w regexp в perl regexp и в PCRE. PCRE / perl не являются регулярными выражениями POSIX, они просто совсем другое.

Теперь, когда GNU grep -P использует PCRE, у него такая же проблема, как и без -P . Его можно использовать там, используя (*UCP) (хотя это также имеет побочные эффекты в не-UTF8-локалях).

GNU sed также использует регулярные выражения GNU libc для собственных регулярных выражений. Он использует его таким образом, хотя в нем нет такой же ошибки, как GNU grep .

GNU sed не поддерживает PCRE. В коде есть некоторые доказательства, которые были предприняты ранее, но, похоже, это не похоже на повестку дня.

Если вам нужны регулярные выражения Perl, просто используйте perl .

В противном случае я бы сказал, что вместо того, чтобы пытаться полагаться на фиктивную нестандартную особенность вашей конкретной реализации sed / grep , было бы лучше придерживаться стандарта и использовать [_[:alnum:]] .

Вы правы – \w является частью регулярных выражений, совместимых с PCRE-perl. Однако это не является частью стандартного регулярного выражения. http://www.regular-expressions.info/posix.html

Некоторые версии sed могут его поддерживать, но я бы предложил, чтобы самый простой способ – использовать perl в режиме sed , указав флаг -p . (Наряду с -e ). (Более подробно в perlrun )

Но вам не нужно [] вокруг этого в этом примере – это для групп действительных вещей.

 echo here | perl -pe 's/\w+/gone/' 

Или в Windows:

 C:\>echo here | perl -pe "s/\w+/gone/" gone C:\>echo here | perl -pe "s/[\w\/]+/gone/" gone 

См. perlre для большего количества материалов PCRE.

Вы можете получить perl здесь: http://www.activestate.com/activeperl/downloads

Я подозреваю, что grep и sed решают иначе, когда применять [] и когда развернуть \w . В perl regex \w означает любой символ слова, а [] определяет группу для применения любого из символов внутри в качестве соответствия. Если вы «развернете» \w перед [] это будет класс символов всех символов слова. Если вместо этого вы сделаете [] сначала у вас будет класс символов с двумя символами \ и w чтобы он соответствовал любому шаблону, содержащему один или несколько из этих двух символов.

Таким образом, кажется, что sed видит [] и рассматривает его как содержащую точные символы, чтобы соответствовать вместо того, чтобы выполнять специальную последовательность \w как perl и grep . Конечно, [] совершенно не нужны в этом примере, но можно представить себе случаи, когда это было бы важно, но тогда вы могли бы заставить его работать с парсерами и орками.