Как преобразовать регулярное выражение в допустимом формате .NET в допустимый формат Java? - PullRequest
1 голос
/ 02 августа 2009

Я хочу использовать следующее регулярное выражение, написанное в коде C # .NET, в коде Java, но я не могу правильно его преобразовать, не могли бы вы мне помочь?

Regex(@"\w+:\/\/(?<Domain>[\x21-\x22\x24-\x2E\x30-\x3A\x40-\x5A\x5F\x61-\x7A]+)(?<Relative>/?\S*)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

Ответы [ 3 ]

2 голосов
/ 02 августа 2009

У Java нет нотации @ строки. Итак, убедитесь, что вы избегаете всех '\' в вашем регулярном выражении. (\w+ becomes> \\w+, \/ becomes> \\/, \x21 becomes> \\x21, etc. )

1 голос
/ 02 августа 2009

Самый прямой перевод будет:

Pattern p = Pattern.compile(
  "\\w+://([\\x21-\\x22\\x24-\\x2E\\x30-\\x3A\\x40-\\x5A\\x5F\\x61-\\x7A]+)(/?\\S*)",
  Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

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

Но есть несколько проблем с оригинальным регулярным выражением:

  • Модификатор RegexOptions.Compiled не делает то, о чем вы, вероятно, думаете. В частности, это не относится к методу Java compile(); это просто фабричный метод, примерно эквивалентный конструктору C # new Regex(). Модификатор Compiled заставляет регулярное выражение скомпилировать в байт-код CIL , что может значительно ускорить его сопоставление, но при значительных затратах на предварительную обработку и использование памяти - и эта память никогда не получает мусор. собраны. Если вы не часто используете регулярное выражение, опция Compiled, вероятно, приносит больше вреда, чем пользы, с точки зрения производительности.

  • Модификатор IgnoreCase/CASE_INSENSITIVE не имеет смысла, так как ваше регулярное выражение всегда совпадает с прописными и строчными вариантами, где бы оно ни совпадало с буквами.

  • Модификатор Singleline/DOTALL не имеет смысла, так как вы никогда не используете метасимвол точки.

  • В регулярных выражениях .NET сокращение класса символов \w поддерживает Unicode, что эквивалентно [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]. В Java это только ASCII - [A-Za-z0-9_] - что, кажется, больше соответствует тому, как вы его используете (вы могли бы «заглушить» его в .NET с помощью модификатора RegexOptions.ECMAScript).

Таким образом, фактический перевод будет выглядеть примерно так:

Pattern p = Pattern.compile("\\w+://([\\w!\"$.:@]+)(?:/(\\S*))?");
1 голос
/ 02 августа 2009

Именованные группы выполняются в .NET иначе, чем во всех других разновидностях Regex. У вас есть:

(?<Domain>pattern)

Java (и все остальные) ожидают:

(?P<Domain>pattern)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...