Regex - Использование коротких символов внутри класса символов - PullRequest
1 голос
/ 31 марта 2012

Мне необходимо выполнить некоторые операции, в которых используются регулярные выражения.

Строка, с которой я работаю:

/dev/fd0        /media/floppy0  auto    rw,us

По сути, я хочу взять первые двапараметры (/dev/fd0 и /media/floppy0), и я хочу игнорировать все после этого.Чтобы достичь, я попробовал регулярные выражения, показанные ниже.Мой вопрос: почему следующие регулярные выражения дают разные результаты?

Регулярное выражение 1:

grep -o '/dev/f\S*\s*\S*' /etc/fstab

Вывод (вывод, который я ожидаю):

/dev/fd0        /media/floppy0

Регулярное выражение 2:

grep -o '/dev/f[\S]*\s*[\S]*' /etc/fstab

Вывод:

/dev/f

Регулярное выражение 3:

grep -o '/dev/f[^\s]*\s[^\s]*' /etc/fstab

Вывод:

/dev/fd0        /media/floppy0  auto    rw,u

Я не понимаю, почему 2 и 3 не выдают тот же результат, что и 1. Я вижу это так, что для 2 не должно иметь значения, ставлю ли я символ короткой руки без пробелов (\S)внутри класса персонажа.То же самое касается 3. Кроме того, почему 2 отличается от 3?Разве [\S] не совпадает с [^\s]?

1 Ответ

2 голосов
/ 31 марта 2012

Полагаю, я не могу говорить о том, должны ли они «должны» быть разными - есть много механизмов регулярных выражений, в которых ваши интерпретации были бы правильными - но в POSIX Basic Regular Expressions (BRE; тип регулярного выражения, который grep использует по умолчанию), [\S] - это класс символов, содержащий \ и S, а [^\s] - это класс символов, содержащий все символы, кроме \ и s.(Это согласно спецификации, которая требует, чтобы как в BRE, так и в ERE, "Специальные символы '.', '*', '[' и '\' (точка, звездочка, левая скобка и обратный слеш,соответственно) утратит свое особое значение в выражении в скобках. "[ ссылка ]) Эквивалент класса символов внутри \s равен [:space:]:

grep -o '/dev/f[^[:space:]]*\s*[^[:space:]]*' /etc/fstab

Некоторые версииgrep поддерживает нестандартную опцию -P для использования Perl-совместимых регулярных выражений (PCRE) вместо регулярных выражений POSIX.Perl-совместимые регулярные выражения имеют описанное вами поведение, поэтому, если ваш grep поддерживает этот параметр, вы можете использовать его следующим образом:

grep -o -P '/dev/f[\S]*\s*[\S]*' /etc/fstab
grep -o -P grep -o '/dev/f[^\s]*\s[^\s]*' /etc/fstab
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...