Подтвердить что ты не робот

Являются ли регулярные выражения Java и С# совместимыми?

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

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

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

4b9b3361

Ответ 1

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

Класс символов

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

Квантор

  • ?+, *+, ++ и {m,n}+ (притяжательные кванторы)
    • .NET НЕТ
    • Java ДА

Цитата

  • \Q...\E выводит строку метасимволов
    • .NET НЕТ
    • Java ДА
  • \Q...\E выводит строку метасимволов класса символов (в наборах символов)
    • .NET НЕТ
    • Java ДА

Конструкция соответствия

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

утверждения

  • (?<=text) (положительный lookbehind)
    • .NET Переменная-ширина
    • Java Очевидная ширина
  • (?<!text) (отрицательный lookbehind)
    • .NET Переменная-ширина
    • Java Очевидная ширина

Параметры режима/флаги

Разное

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

Ссылки

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Сравните их самостоятельно: Java: С#:

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

Ответ 6

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

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

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

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

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

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

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

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

  • Нет режима "Явный захват".

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

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

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