Java和C#正则表达式是否兼容?

时间:2009-02-11 20:18:50

标签: c# java .net regex

两种语言都声称使用Perl样式的正则表达式。如果我有一种语言测试正则表达式的有效性,它会在另一种语言中工作吗?正则表达式语法在哪里不同?

这里的用例是一个C#(.NET)UI,它与最终的Java后端实现进行通信,该实现将使用正则表达式来匹配数据。

请注意,我只需要担心匹配,而不是提取匹配数据的部分。

6 个答案:

答案 0 :(得分:93)

存在很多(很多)差异。

角色等级

  1. 字符类减法[abc-[cde]]
    • .NET YES(2.0)
    • Java:通过字符类交集和否定模拟:[abc&&[^cde]]
  2. 字符类交集[abc&&[cde]]
    • .NET:通过字符类减法和否定模拟:[abc-[^cde]]
    • Java
  3. \p{Alpha} POSIX字符类
    • .NET
    • Java YES(US-ASCII)
  4. (?x)模式 COMMENTS / IgnorePatternWhitespace 下,字符类中的空格(U + 0020)为重要
    • .NET
    • Java
  5. Unicode Category(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 Category(Lu,Ll,Lt,...)
    • .NET \p{Lu}仅限
    • Java
      • 来自Java 5:\p{Lu}\p{IsLu}
      • 来自Java 7:\p{general_category=Lu}\p{gc=Lu}
  7. Unicode Block
    • .NET :仅限\p{IsBasicLatin}。 (Supported Named Blocks
    • Java :(块名称为free-casing)
      • 来自Java 5:\p{InBasicLatin}
      • 来自Java 7:\p{block=BasicLatin}\p{blk=BasicLatin}
  8. 所有长版块名称中允许的空格和下划线(例如BasicLatin可以写为Basic_LatinBasic Latin
    • .NET
    • Java (Java 5)
  9. 量词

    1. ?+*+++{m,n}+(占有量词)
      • .NET
      • Java
    2. 报价

      1. \Q...\E转义一串元字符
        • .NET
        • Java
      2. \Q...\E转义一串字符类元字符(在字符集中)
        • .NET
        • Java
      3. 匹配构造

        1. 条件匹配(?(?=regex)then|else)(?(regex)then|else)(?(1)then|else)(?(group)then|else)
          • .NET
          • Java
        2. 命名捕获组并命名为反向引用
          • .NET
            • 捕获群组:(?<name>regex)(?'name'regex)
            • 反向引用:\k<name>\k'name'
          • Java Java 7):
            • 捕获群组:(?<name>regex)
            • 反向引用:\k<name>
        3. 多个捕获组可以具有相同的名称
          • .NET
          • Java (Java 7)
        4. 平衡群组定义(?<name1-name2>regex)(?'name1-name2'subexpression)
          • .NET
          • Java
        5. 断言

          1. (?<=text)(正面观察)
            • .NET 可变宽度
            • Java 明显的宽度
          2. (?<!text)(负面观察)
            • .NET 可变宽度
            • Java 明显的宽度
          3. 模式选项/标志

            1. ExplicitCapture选项(?n)
              • .NET
              • Java
            2. 其它

              1. (?#comment)内联评论
                • .NET
                • Java
              2. 参考

答案 1 :(得分:6)

结帐:http://www.regular-expressions.info/refflavors.html 该网站上有大量的正则表达式信息,并且有一个很好的图表,详细说明了java和amp;之间的差异。 。净。

答案 2 :(得分:4)

c#regex对命名组(?<name>)有自己的约定。我不知道有任何其他差异。

答案 3 :(得分:2)

.NET Regex支持计数,因此您可以匹配嵌套括号,这是您通常无法使用正则表达式执行的操作。根据掌握正则表达式,这是为数不多的实现之一,所以这可能是一个区别。

答案 4 :(得分:2)

Java使用标准的Perl类型正则表达式以及POSIX正则表达式。看看关于正则表达式的C#文档,看起来Java具有所有C#正则表达式语法,但不是相反。

自己比较:JavaC#:

修改 Currently, no other regex flavor supports Microsoft's version of named capture.

答案 5 :(得分:1)

根据我的经验:

与.NET 2.0正则表达式相比,Java 7正则表达式:

  • 不支持组名中的下划线符号

  • 不支持具有相同名称(在同一正则表达式中)的组(尽管在使用“或”的表达式中它可能非常有用!)

  • 没有捕获任何内容的群组的值为null,而不是空字符串

  • 索引为0的组也包含整个匹配项(与.NET中相同)但不包含在groupCount()

  • 中 替换表达式中的
  • 组后退引用也用美元符号(例如$ 1)表示,但如果相同的表达式包含美元符号作为行尾 标记 - 然后后退参考美元应该被转义(\ $),否则在Java中我们得到“非法组引用”错误

  • 行尾符号($)表现得很贪婪。例如,考虑以下表达式(给出Java字符串):“bla(bla(?:$ | \ r \ n))+)?$”。这里是最后一个 将不会捕获文本行!要捕获它,我们必须用“\ z”替换“$”。

  • 没有“Explicit Capture”模式。

  • 空字符串不满足^。{0} $ pattern。

  • 符号“ - ”在方括号内使用时必须转义。也就是说,模式“[a-z + - ] +”与Java中的字符串“f + g-h”不匹配,但在.NET中也是如此。匹配 在Java中,模式应该看起来像(给出了Java字符串):“[a-z + \ - ] +”。

注意:“(给出了Java字符串)” - 只是为了解释表达式中的双重转义。