如何将有效.NET格式的正则表达式转换为有效的Java格式?

时间:2009-08-02 01:15:49

标签: java .net regex

我想在Java代码中使用以下正则表达式,这是在C#.NET代码中编写的,但我似乎无法将其正确转换,你可以帮助我吗?

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

3 个答案:

答案 0 :(得分:2)

Java没有@ string表示法。因此,请确保您在正则表达式中删除所有'\'。 (\w+ becomes> \\w+, \/ becomes> \\/, \x21 becomes> \\x21, etc. )

答案 1 :(得分:1)

在.NET中,命名组的执行方式与所有其他Regex风格不同。你有:

(?<Domain>pattern)

Java(以及其他所有人)期望:

(?P<Domain>pattern)

答案 2 :(得分:1)

最直接的翻译是:

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_] - 它似乎更符合你使用它的方式(你可以使用RegexOptions.ECMAScript修饰符在.NET中“愚蠢” )。

所以实际翻译会更像这样:

Pattern p = Pattern.compile("\\w+://([\\w!\"$.:@]+)(?:/(\\S*))?");