如何将这个Perl正则表达式翻译成Java?
如何将这个Perl正则表达式翻译成Java如何将这个Perl正则表达式翻译成Java?,java,regex,perl,Java,Regex,Perl,如何将这个Perl正则表达式翻译成Java /pattern/i /pattern/i 编译时,它与我的“模式”不匹配,它失败了 Pattern p = Pattern.compile("/pattern/i"); Matcher m = p.matcher("PattErn"); System.out.println(m.matches()); // prints "false" Pattern p = Pattern.compile("/pattern/i"
/pattern/i
/pattern/i
编译时,它与我的“模式”不匹配,它失败了
Pattern p = Pattern.compile("/pattern/i");
Matcher m = p.matcher("PattErn");
System.out.println(m.matches()); // prints "false"
Pattern p = Pattern.compile("/pattern/i");
Matcher m = p.matcher("PattErn");
System.out.println(m.matches()); // prints "false"
Perl等效于:
/pattern/i
在Java中,将是:
Pattern p = Pattern.compile("(?i)pattern");
或者干脆做:
System.out.println("PattErn".matches("(?i)pattern"));
请注意,“string”。匹配(“模式”)
根据整个输入字符串验证模式。换句话说,以下内容将返回false:
"foo pattern bar".matches("pattern")
Java正则表达式没有分隔符,并对修饰符使用单独的参数:
Pattern p = Pattern.compile("pattern", Pattern.CASE_INSENSITIVE);
如何将这个Perl正则表达式翻译成Java
/pattern/i
/pattern/i
你不能
这有很多原因。以下是一些:
- Java不像Perl那样支持正则表达式语言。它缺乏对字形的支持(如
和完整的属性支持(如\X)
),缺少Unicode命名字符,没有\p{statement\u Break=scocontinue}
分支重置操作符,没有命名的捕获组或逻辑(?|…|…)
Java 7之前的转义,没有递归正则表达式,等等。我可以写一本关于Java在这里缺失的东西的书:习惯于回到一个非常原始的、与您习惯的相比难以使用的正则表达式引擎\X{…}
- 另一个更糟糕的问题是,您有类似的仿AMI,如
和\w
和\b
,甚至\s
和\p{alpha}
,它们在Java中的行为与Perl不同;在某些情况下,Java版本完全不可用,并且有缺陷。这是因为Perl紧随其后,但在Java7之前,Java没有。您必须从Java 7添加\p{lower}
标志,以使这些类停止被破坏。如果你不能使用Java7,那么现在就放弃吧,因为Java在Java7之前还有很多Unicode错误,不值得花时间去处理它们UNICODE\u字符\u类
- Java通过
和^
和$
处理换行符,但Perl希望Unicode换行符是
。您应该查看\R
,了解那里发生了什么UNIX\u行
- Java默认情况下不应用任何Unicode大小写。确保将
标志添加到编译中。否则,你不会得到像各种希腊符号都相互匹配的东西UNICODE\u大小写
- 最后,它是不同的,因为Java最多只做简单的大小写折叠,而Perl总是做完整的大小写折叠。这意味着您将不会得到
在Java中不敏感地匹配“SS”大小写,以及类似的相关问题\xDF
CASE_INSENSITIVE | UNICODE_CASE | UNICODE_CHARACTER_CLASSES
这相当于模式字符串中嵌入的“(?iuU)”
请记住,Java中的匹配并不意味着匹配,这是很反常的
编辑 下面是故事的其余部分 编译时,它与我的“模式”不匹配,它失败了
Pattern p = Pattern.compile("/pattern/i");
Matcher m = p.matcher("PattErn");
System.out.println(m.matches()); // prints "false"
Pattern p = Pattern.compile("/pattern/i");
Matcher m = p.matcher("PattErn");
System.out.println(m.matches()); // prints "false"
图案周围不应该有斜线
你所能做的就是翻译
$line = "I have your PaTTerN right here";
if ($line =~ /pattern/i) {
print "matched.\n";
}
这边
import java.util.regex.*;
String line = "I have your PaTTerN right here";
String pattern = "pattern";
Pattern regcomp = Pattern.compile(pattern, CASE_INSENSITIVE
| UNICODE_CASE
// comment next line out for legacy Java \b\w\s breakage
| UNICODE_CHARACTER_CLASSES
);
Matcher regexec = regcomp.matcher(line);
if (regexec.find()) {
System.out.println("matched");
}
好了,看看这有多容易
Java的另一个缺点是编译时编译模式。Me,我一直认为编译时是编译的最佳时间,但试着告诉Java这一点。Java使得实现非常简单的程序健全性度量变得非常困难,这是您在每个程序中始终需要做的事情。这个设计缺陷是一个巨大的麻烦,因为在你的程序进行到一半的时候,你会因为一些本应该在编译时被捕获的东西而出现异常,而你的程序的其余部分正在被编译。就像性交中断一样让人恼火,因为你正在顺利完成你的事业,一切都毁了
我没有在上面的代码中实现解决这一恼人问题的方法,但是您可以通过一些静态初始化来伪造它。是否有一个网站如您所述列出了常见的Perl->Java翻译规则?我不知道。Java的正则表达式模式看起来很像Perl,只是没有分隔符。@mac这有您需要了解的关于Java正则表达式的所有信息:包括一个标记列表,如不区分大小写和一些examples@Bart:如果你看得不太仔细的话,它们会让你看起来很像Perl,但它们不会这样做。请看我的答案。@tchrist,是的,Perl的正则表达式实现要强大得多。我的评论是:“看起来一样”,我的意思是在语法层面:Java支持大部分PCRE功能。我总是能看到你的答案(wrtregex,也就是说:总是非常有用!)。Perl对不区分大小写的匹配进行完全的Unicode大小写折叠。因此,这是不等价的。+1表示“在那里,看看这不是多么容易:)”。哦,还有一个激动人心的回答。