Перевести 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.

Другие вопросы по тегам