Java和C#正则expression式是否兼容?
两种语言都声称使用Perl风格的正则expression式。 如果我有一种语言testing正则expression式的有效性,它会在另一种语言中工作吗? 正则expression式语法在哪里有所不同?
这里的用例是一个C#(.NET)UI与最终的Java后端实现进行交互,后者将使用正则expression式来匹配数据。
请注意,我只需要担心匹配,而不是提取匹配数据的部分。
有很多(很多)的差异。
字符类
- 字符类减法
[abc-[cde]]
- .NET 是(2.0)
- Java:通过字符类交集和否定模拟:
[abc&&[^cde]]
)
- 字符类相交
[abc&&[cde]]
- .NET:通过字符类减法和否定模拟:
[abc-[^cde]]
) - Java 是的
- .NET:通过字符类减法和否定模拟:
-
\p{Alpha}
POSIX字符类- .NET NO
- Java 是(US-ASCII)
- 在
(?x)
模式COMMENTS
/IgnorePatternWhitespace
,字符类中的空格(U + 0020)很重要 。- .NET 是的
- Java NO
- 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}
- 从Java 5开始:
- .NET 是 :
- Unicode类别 (Lu,Ll,Lt,…)
- .NET 是 :
\p{Lu}
表单只 - Java 是的 :
- 从Java 5开始:
\p{Lu}
,\p{IsLu}
- 从Java 7开始:
\p{general_category=Lu}
,\p{gc=Lu}
- 从Java 5开始:
- .NET 是 :
- Unicode块
- .NET 是 :
\p{IsBasicLatin}
只。 ( 受支持的命名块 ) - Java 是的 :(块的名称是自由套pipe)
- 从Java 5开始:
\p{InBasicLatin}
- 从Java 7开始:
\p{block=BasicLatin}
,\p{blk=BasicLatin}
- 从Java 5开始:
- .NET 是 :
- 所有长块名称都允许使用空格和下划线(例如
BasicLatin
可以写成Basic_Latin
或Basic Latin
)- .NET NO
- Java YES (Java 5)
量词
-
?+
,*+
,++
和{m,n}+
(占有量词)- .NET NO
- Java 是的
行情
-
\Q...\E
转义了一串元字符- .NET NO
- Java 是的
-
\Q...\E
转义字符类元字符的string(在字符集中)- .NET NO
- Java 是的
匹配构造
- 条件匹配
(?(?=regex)then|else)
,(?(regex)then|else)
,(?(1)then|else)
或(?(group)then|else)
- .NET 是的
- Java NO
- 命名捕获组并命名为反向引用
- .NET 是 :
- 捕获组:
(?<name>regex)
或(?'name'regex)
- 反向引用:
\k<name>
或\k'name'
- 捕获组:
- Java 是 ( Java 7 ):
- 捕获组:
(?<name>regex)
- 反向:
\k<name>
- 捕获组:
- .NET 是 :
- 多个捕获组可以具有相同的名称
- .NET 是的
- Java NO (Java 7)
- 平衡组定义
(?<name1-name2>regex)
或(?'name1-name2'subexpression)
- .NET 是的
- Java NO
断言
-
(?<=text)
(积极向后看)- .NET 可变宽度
- Java 明显的宽度
-
(?<!text)
(负面后顾)- .NET 可变宽度
- Java 明显的宽度
模式选项/标志
-
ExplicitCapture
选项(?n)
- .NET 是的
- Java NO
杂
-
(?#comment)
内嵌注释- .NET 是的
- Java NO
参考
- regular-expressions.info – 不同的正则expression式的比较
- MSDN Library参考 – .NET Framework 4.5 – 正则expression式语言
- 模式(Java平台SE 7)
查看: http : //www.regular-expressions.info/refflavors.html大量的正则expression式信息,并有一个很好的图表,详细介绍了java和.net之间的差异。
C#正则expression式有自己的约定命名组(?<name>)
。 我不知道其他的区别。
.NET的正则expression式支持计数,所以你可以匹配嵌套的括号,这是你通常不能用正则expression式做的事情。 根据掌握正则expression式,这是less数几个实现之一,所以这可能是一个区别。
Java使用标准的Perltypes正则expression式以及POSIX正则expression式。 看看正则expression式的C#文档,它看起来像Java具有所有C#正则expression式的语法,但不是相反。
自己比较一下: Java : C#:
编辑: 目前,没有其他正则expression式支持微软的命名捕获版本。
从我的经验:
与.NET 2.0正则expression式相比,Java 7正则expression式:
-
组名中的下划线符号不受支持
-
不支持具有相同名称的组(在相同的正则expression式中)(尽pipe在使用“或”的expression式中可能会非常有用!)
-
没有捕获任何东西的组的值都是
null
而不是空string -
索引为0的组也包含整个匹配(与.NET相同),但不包括在
groupCount()
-
replaceexpression式中的组返回引用也用美元符号(例如$ 1)表示,但是如果同一个expression式包含美元符号作为行尾标记 – 那么后面的引用美元应该被转义(\ $),否则在Java我们得到“非法组参考”错误
-
行尾符号($)performance为贪婪行为。 例如,考虑下面的expression式(给出Javastring):“bla(bla(?:$ | \ r \ n))+)?$”。 这里的最后一行文字将不被捕获! 要捕获它,我们必须用“\ z”replace“$”。
-
没有“显式捕捉”模式。
-
空string不满足^。{0} $模式。
-
符号“ – ”在方括号内使用时必须转义。 也就是说,在Java中,模式“[a-z + – ] +”与string“f + gh”不匹配,但是在.NET中。 要在Java中匹配,模式应该看起来像(给出了Javastring):“[a-z + \ – ] +”。
注意:“(给出的Javastring)” – 只是为了解释expression式中的双重转义。