Совместимы ли регулярные выражения Java и C #? - PullRequest
43 голосов
/ 11 февраля 2009

Оба языка утверждают, что используют регулярные выражения в стиле Perl. Если у меня будет один языковой тест на правильность регулярного выражения, будет ли он работать на другом? Где синтаксис регулярного выражения различается?

В данном случае используется пользовательский интерфейс C # (.NET), который взаимодействует с возможной внутренней реализацией Java, которая будет использовать регулярное выражение для сопоставления данных.

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

Ответы [ 6 ]

93 голосов
/ 13 февраля 2009

Есть довольно много различий.

Класс персонажа

  1. Вычитание классов символов [abc-[cde]]
    • .NET ДА (2.0)
    • Java: эмулируется через пересечение и отрицание класса символов: [abc&&[^cde]])
  2. Пересечение классов символов [abc&&[cde]]
    • .NET: эмулируется с помощью вычитания и отрицания класса символов: [abc-[^cde]])
    • Java ДА
  3. \p{Alpha} Класс символов POSIX
    • .NET NO
    • Java ДА (US-ASCII)
  4. В режиме (?x) COMMENTS / IgnorePatternWhitespace, пробел (U + 0020) в классе символов значительный .
    • .NET ДА
    • Java NO
  5. Категория Unicode (L, M, N, P, S, Z, C)
    • .NET ДА : \p{L} только форма
    • Java ДА :
      • Из Java 5: \pL, \p{L}, \p{IsL}
      • Из Java 7: \p{general_category=L}, \p{gc=L}
  6. Категория Unicode (Lu, Ll, Lt, ...)
    • .NET ДА : \p{Lu} только форма
    • Java ДА :
      • Из Java 5: \p{Lu}, \p{IsLu}
      • Из Java 7: \p{general_category=Lu}, \p{gc=Lu}
  7. Блок Unicode
  8. Пробелы и подчеркивания разрешены во всех длинных именах блоков (например, BasicLatin можно записать как Basic_Latin или Basic Latin)
    • .NET NO
    • Java ДА (Java 5)

Квантор

  1. ?+, *+, ++ и {m,n}+ (собственнические квантификаторы)
    • .NET NO
    • Java ДА

цитата

  1. \Q...\E экранирует цепочку метасимволов
    • .NET NO
    • Java ДА
  2. \Q...\E экранирует строку метасимволов классов символов (в наборах символов)
    • .NET NO
    • Java ДА

Соответствующая конструкция

  1. Условное сопоставление (?(?=regex)then|else), (?(regex)then|else), (?(1)then|else) или (?(group)then|else)
    • .NET ДА
    • Java NO
  2. Именованная группа захвата и именная обратная ссылка
    • .NET ДА :
      • Группа захвата: (?<name>regex) или (?'name'regex)
      • Ссылка: \k<name> или \k'name'
    • Java ДА ( Java 7 ):
      • Захватывающая группа: (?<name>regex)
      • Ссылка: \k<name>
  3. Несколько групп захвата могут иметь одинаковое имя
    • .NET ДА
    • Java NO (Java 7)
  4. Определение балансировочной группы (?<name1-name2>regex) или (?'name1-name2'subexpression)
    • .NET ДА
    • Java NO

1287 * Утверждения * (?<=text) (позитивный взгляд сзади) .NET Переменная ширина Java Очевидная ширина (?<!text) (негативный взгляд сзади) .NET Переменная ширина Java Очевидная ширина Параметры режима / Флаги

  1. ExplicitCapture опция (?n)
    • .NET ДА
    • Java NO

Разное

  1. (?#comment) встроенные комментарии
    • .NET ДА
    • Java NO

Ссылки

6 голосов
/ 12 февраля 2009

Выезд: http://www.regular -expressions.info / refflavors.html На этом сайте есть много информации о регулярных выражениях, и есть хорошая диаграмма, которая детализирует различия между java и .net.

4 голосов
/ 11 февраля 2009

c # regex имеет собственное соглашение для именованных групп (?<name>). Я не знаю никаких других отличий.

2 голосов
/ 11 февраля 2009

Java использует стандартное регулярное выражение типа Perl, а также регулярное выражение POSIX. Глядя на документацию C # по регулярным выражениям, кажется, что Java имеет весь синтаксис регулярных выражений C #, но не наоборот.

Сравните их сами: Java : C #:

EDIT: В настоящее время никакие другие разновидности регулярных выражений не поддерживают версию именованного захвата Microsoft.

2 голосов
/ 11 февраля 2009

.NET Regex поддерживает подсчет, поэтому вы можете сопоставлять вложенные скобки, чего вы обычно не можете делать с регулярным выражением. Согласно «Освоению регулярных выражений», это одна из немногих реализаций, которая может это сделать, так что это может иметь значение.

1 голос
/ 01 марта 2017

Из моего опыта:

Регулярные выражения Java 7 по сравнению с регулярными выражениями .NET 2.0:

  • Символ подчеркивания в именах групп не поддерживается

  • Группы с одинаковыми именами (в одном и том же регулярном выражении) не поддерживаются (хотя это может быть действительно полезно в выражениях, использующих "или"!)

  • Группы, которые ничего не захватили, имеют значение null, а не пустую строку

  • Группа с индексом 0 также содержит все совпадения (как в .NET), НО не входит в groupCount()

  • Групповая обратная ссылка в выражениях замены также обозначается знаком доллара (например, $ 1), но если то же выражение содержит знак доллара в качестве конца строки marker - тогда обратный ссылочный доллар должен быть экранирован (\ $), иначе в Java мы получим ошибку «недопустимая групповая ссылка»

  • Символ конца строки ($) ведет себя жадно. Рассмотрим, например, следующее выражение (задана Java-строка): "bla (bla (?: $ | \ R \ n)) +)? $". Здесь последний строка текста НЕ будет захвачена! Чтобы захватить его, мы должны заменить «$» на «\ z».

  • Режим «Явный захват» отсутствует.

  • Пустая строка не соответствует шаблону ^. {0} $.

  • Символ "-" должен быть экранирован при использовании в квадратных скобках. То есть шаблон "[a-z + -] +" не соответствует строке "f + g-h" в Java, но в .NET. Чтобы соответствовать в Java шаблон должен выглядеть так (задана строка Java): "[a-z + \ -] +".

ПРИМЕЧАНИЕ: «(дана строка Java)» - просто для объяснения двойного экранирования в выражении.

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