Перевести Perl регулярные выражения в.NET
У меня есть несколько полезных регулярных выражений в Perl. Есть ли простой способ перевести их на диалект регулярных выражений.NET?
Если нет, то есть ли краткая справка о различиях?
3 ответа
В http://www.regular-expressions.info/refflavors.html есть большая таблица сравнения.
Большинство основных элементов одинаковы, отличия:
Незначительные различия:
- Escape-последовательности Юникода. В.NET это
\u200A
в Perl это\x{200A}
, \v
в.NET это просто вертикальная табуляция (U+000B), в Perl это класс "вертикальный пробел". Есть конечно\V
в Perl из-за этого.- Условное выражение для именованной ссылки в.NET:
(?(name)yes|no)
, но(?(<name>)yes|no)
в перл.
Некоторые элементы только для Perl:
- Посессивные квантификаторы (
x?+
,x*+
,x++
так далее). Использовать невыражающее подвыражение ((?>…)
) вместо - Именованная escape-последовательность Юникода
\N{LATIN SMALL LETTER X}
,\N{U+200A}
, - Чехол складной и убегающий
\l
(нижний регистр следующий символ),\u
(верхний регистр следующий символ).\L
(нижний регистр),\U
(верхний регистр),\Q
(цитируйте метасимволы) до\E
,
- Сокращенное обозначение свойства Юникод
\pL
а также\PL
, Вы должны включить скобки в.NET, например\p{L}
, - Странные вещи, такие как
\X
,\C
, - Специальные классы персонажей, такие как
\v
,\V
,\h
,\H
,\N
,\R
- Обратная ссылка на конкретную или предыдущую группу
\g1
,\g{-1}
, Вы можете использовать только абсолютный групповой индекс в.NET. - Именованные обратные ссылки
\g{name}
, использование\k<name>
вместо. - Класс персонажей POSIX
[[:alpha:]]
, - Шаблон сброса ветви
(?|…)
\K
, Используйте оглядку назад ((?<=…)
) вместо- Утверждение оценки кода
(?{…})
, постонированное подвыражение(??{…})
, - Ссылка на субэкспрессию (рекурсивный шаблон)
(?0)
,(?R)
,(?1)
,(?-1)
,(?+1)
,(?&name)
, - Предикат некоторых условных выражений специфичен для Perl:
- код
(?{…})
- рекурсивный
(R)
,(R1)
,(R&name)
- определять
(DEFINE)
,
- код
- Специальные глаголы контроля возврата
(*VERB:ARG)
- Синтаксис Python
(?P<name>…)
, использование(?<name>…)
вместо.(?P=name)
, использование\k<name>
вместо.(?P>name)
, Нет аналога в.NET.
Некоторые элементы только для.NET:
- Задняя часть переменной длины. В Perl для позитивного просмотра используйте
\K
вместо. - Произвольное регулярное выражение в условном выражении
(?(pattern)yes|no)
, - Вычитание класса персонажа (недокументированное?)
[a-z-[d-w]]
- Балансировочная группа
(?<-name>…)
, Это может быть смоделировано с утверждением оценки кода(?{…})
с последующим(?&name)
,
Рекомендации:
Они были разработаны для совместимости с регулярными выражениями Perl 5. Таким образом, регулярные выражения Perl 5 должны работать только в.NET.
Вы можете перевести некоторые RegexOptions
следующее:
[Flags]
public enum RegexOptions
{
Compiled = 8,
CultureInvariant = 0x200,
ECMAScript = 0x100,
ExplicitCapture = 4,
IgnoreCase = 1, // i in Perl
IgnorePatternWhitespace = 0x20, // x in Perl
Multiline = 2, // m in Perl
None = 0,
RightToLeft = 0x40,
Singleline = 0x10 // s in Perl
}
Другой совет - использовать дословные строки, чтобы вам не нужно было экранировать все эти escape-символы в C#:
string badOnTheEyesRx = "\\d{4}/\\d{2}/\\d{2}";
string easierOnTheEyesRx = @"\d{4}/\d{2}/\d{2}";
Это действительно зависит от сложности регулярного выражения - многие из них будут работать одинаково из коробки.
Посмотрите на этот шпаргалку.NET, чтобы узнать, делает ли оператор то, что вы ожидаете.
Я не знаю ни одного инструмента, который автоматически переводил бы между диалектами RegEx.