Java 索引nnn附近的未闭合字符类
我借用了一些PHP Textile实现(开源,适当属性化)中相当复杂的正则表达式来实现一个简单但功能不完全的Java实现textile4j,我正在将其移植到github并同步到Maven central(编写原始代码是为了为Java博客平台blojsom提供插件;这是Maven Central提供blojsom依赖项的更大努力的一部分) 不幸的是,纺织正则表达式(当它们在PHP中的Java 索引nnn附近的未闭合字符类,java,php,regex,regexbuddy,Java,Php,Regex,Regexbuddy,我借用了一些PHP Textile实现(开源,适当属性化)中相当复杂的正则表达式来实现一个简单但功能不完全的Java实现textile4j,我正在将其移植到github并同步到Maven central(编写原始代码是为了为Java博客平台blojsom提供插件;这是Maven Central提供blojsom依赖项的更大努力的一部分) 不幸的是,纺织正则表达式(当它们在PHP中的preg\u replace\u callback上下文中工作时)在Java中失败,出现以下异常: java.uti
preg\u replace\u callback
上下文中工作时)在Java中失败,出现以下异常:
java.util.regex.PatternSyntaxException:索引217附近的未关闭字符类
声明是显而易见的,解决方案是难以捉摸的
以下是PHP实现中的原始多行正则表达式:
return preg_replace_callback('/
(^|(?<=[\s>.\(])|[{[]) # $pre
" # start
(' . $this->c . ') # $atts
([^"]+?) # $text
(?:\(([^)]+?)\)(?="))? # $title
":
('.$this->urlch.'+?) # $url
(\/)? # $slash
([^\w\/;]*?) # $post
([\]}]|(?=\s|$|\)))
/x',callback,input);
我已经使用诸如和之类的在线工具发现了可能导致解析错误的几个方面。但是,这些细节都无法修复错误
我怀疑其中一个字符类中隐藏了一个范围问题,或者某个地方隐藏了一个Unicode顺序,但我找不到它
有什么想法吗
我也很好奇为什么PHP没有抛出类似的错误,例如,我发现一个“被动子表达式”使用RegExr处理得很糟糕,但它没有修复Java异常,也没有改变PHP中的行为,如下所示
在#title
中切换转义参数:
(?:\(([^)]+?)\)(?="))? # $title
...^
(?:(\([^)]+?)\)(?="))? # $title
....^
谢谢,
提姆
编辑:添加纺织正则表达式的Java字符串解释(带转义),由
以下简称:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除上述上述上述上述上述上述::::::::::::::::::::::::::::::::除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除#{124;\\^-\[\\]`+?)(\\/)([^\\ w\\/;]*?)([\\]}]|(?=\\s\\\$\\))”
我不确定您的问题到底出在哪里,但这可能会有所帮助: 在Java中(我相信这是Java独有的),
[
符号(不仅仅是]
符号)保留在字符类中,需要转义
为了与Java兼容,修订后的表达式可能与以下类似:
(^|(?<=[\s>.\(])|[{\[]) # $pre
" # start
(' . $this->c . ') # $atts
([^"]+?) # $text
(?:\(([^)]+?)\)(?="))? # $title
":
('.$this->urlch.'+?) # $url
(\/)? # $slash
([^\w\/;]*?) # $post
([\]}]|(?=\s|$|\)))
/x
(^ |(?.\(])|[{\[])#$pre
“#开始
('.$this->c.)#$atts
([^”]+?)#$text
(?:\([^)]+?)\(?=”))\ \$title
":
('.$this->urlch.+?)#$url
(\/)?\$slash
([^\w\/;]*?)#$post
([\]}]|(?=\s |$|\))
/x
基本上,任何大多数正则表达式风格允许使用字符类(如[a-z;[\]+-]
)的地方,都需要实际使用[a-z,;\[\]+-]
(转义[
带有\
字符)
此转义要求是由Java字符类构造引起的。@CodeJockey是正确的:您的一个字符类中有一个方括号需要转义。
[]
或[^]
没有问题,因为]
是除求反^
之外的第一个字符,但是在Java中,字符类中的任何位置都没有经过scaped的[
是一个语法错误
具有讽刺意味的是,原始正则表达式包含许多甚至在PHP中都不需要的反斜杠。它也会转义/
,因为它使用的是正则表达式分隔符。剔除所有这些后,我提出了以下Java正则表达式:
"(^|(?<=[\\s>.(])|[{\\[])\"((?:(?:\\([^)]+\\))|(?:\\{[^}]+\\})|(?:\\[[^]]+\\])|(?:<(?!>)|(?<!<)>|<>|=|[()]+(?! )))*)([^\"]+?)(?:\\(([^)]+?)\\)(?=\"))?\":([\\w\"$_.+!*'(),\";/?:@=&%#{}|^~\\[\\]`-]+?)(/)?([^\\w/;]*?)([]}]|(?=\\s|$|\\)))"
以下简称::(((:::)以下以下以下::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::[[[[[[除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除\[\\]`-]+?)(/)([^\\w/;]*?)([]}]|(?=\\s |$|\)”
我不知道它是否是最好的正则表达式,也不知道它是如何使用的。实际上,因为它是java,所以需要使用双“\”。@FailedDev-是的,任何
\
字符在放入字符串时都需要转义。上面的例子是用PHP编写的,所以所有的\
字符,包括\s
和\(
中的字符,如果放在Java字符串中,就需要加倍。艾伦,非常感谢您的调查!基本上,textile是一个“mediawiki lite”文本解析器由FARVD fame的Dean Cameron Allen多年前创建。语法显然具有高度传染性,我相信,但不能确定,TextPattern CMS是围绕它构建的。所讨论的正则表达式,取自PHP,作为OP,用于解析Textile的链接语法。在c.2003的某个时候,一个Textile的Java端口被采用Java port有一个正则表达式,它不能处理所有的纺织特性。请参阅OP了解我对正确处理它的兴趣。:)啊,将复杂正则表达式转换为不完全兼容的风格的乐趣——从来都不是一个枯燥的时刻!;)但你知道@FailedDev的答案是错误的,不是吗?无论原始正则表达式在何处使用\
,它都试图匹配文字角括号,而不是单词边界。(我检查文档只是为了确定;它们是Textile文本对齐语法的一部分。)alan,这确实有效,而且更干净,更少的空匹配组(从12到9)。Textile很简洁,但是看着代码,想到TextPattern让我想起这句话:有些人在遇到问题时会想“我知道,我会使用正则表达式。”现在他们有两个问题--杰米·扎温斯基(Jamie Zawinski)
?这就是我出错的原因?因为Java认为我可以通过某种巫术将一个角色类嵌入到另一个角色类中?[/rage]好吧,一个口才好的人想在stackoverflow上解释一下这是件好事。呵呵,这也发生在我身上——我想检查输入中的反斜杠,但我忘记了双重转义(第一次是Java字符串,第二次是正则表达式,我不得不将其写成“\\\”
)我觉得那一行的标题没问题。
(^|(?<=[\s>.\(])|[{\[]) # $pre
" # start
(' . $this->c . ') # $atts
([^"]+?) # $text
(?:\(([^)]+?)\)(?="))? # $title
":
('.$this->urlch.'+?) # $url
(\/)? # $slash
([^\w\/;]*?) # $post
([\]}]|(?=\s|$|\)))
/x
"(^|(?<=[\\s>.(])|[{\\[])\"((?:(?:\\([^)]+\\))|(?:\\{[^}]+\\})|(?:\\[[^]]+\\])|(?:<(?!>)|(?<!<)>|<>|=|[()]+(?! )))*)([^\"]+?)(?:\\(([^)]+?)\\)(?=\"))?\":([\\w\"$_.+!*'(),\";/?:@=&%#{}|^~\\[\\]`-]+?)(/)?([^\\w/;]*?)([]}]|(?=\\s|$|\\)))"