我正在尝试编写一个帮助方法来分解路径表达式,并希望得到一些帮助。请考虑如下四个路径模式(圆括号表示谓词):
item.sub_element.subsubelement(@key = string)
;或者,item..subsub_element(@key = string)
;或者,//subsub_element(@key = string)
;或者,item(@key = string)
正则表达式与那些匹配的是什么?
我想出的是:
((/{2}?[\\w+_*])(\\([_=@#\\w+\\*\\(\\)\\{\\}\\[\\]]*\\))?\\.{0,2})+
我正在读这个:“匹配一个或多个由两个组组成的字符串的出现:第一组由一个或多个带有可选下划线和可选的双正斜杠前缀的单词组成;第二组是可选的并且至少包含一个单词,其他所有字符都是可选的;组由零到两个点跟踪。“
但是,使用Matcher.matches()在第四个示例上运行的测试返回false。那么,我的错误在哪里?
有什么想法吗?
TIA,
FK
修改:尝试使用http://www.regexplanet.com/simple/index.html时,似乎我不知道Matcher.matches()
对象的Matcher.find()
和Matcher
方法之间存在差异。我试图将输入字符串分解为与我的正则表达式匹配的子字符串。因此,我需要使用find()
,而不是matches()
。
Edit2:这就是诀窍
([A-ZA-Z0-9 _] +)\ {0,2}(\(。* \))?
答案 0 :(得分:3)
您可能会发现此网站可用于测试您的正则表达式http://www.fileformat.info/tool/regex.htm。
作为一种通用方法,尝试从处理简单案例的一个构建正则表达式,编写一些测试并使其通过。然后使正则表达式更复杂,以处理其他情况。确保它通过原始测试和新测试。
答案 1 :(得分:3)
我认为你误解了角色课程。我发现,为了测试正则表达式,http://gskinner.com/RegExr/非常有帮助。作为正则表达式的教程,我建议http://www.regular-expressions.info/tutorial.html。
我不完全确定,你想如何分组你的字符串。你的句子似乎暗示,你的第一组只是item
的{{1}}部分,但后来我不确定第二组应该是什么。从我从正则表达式中推断出来的情况来看,我只是将括号前的部分分组到第一组,将括号中的部分分组到第二组。如果我误解了你,你肯定可以修改它。
我没有逃避Java的表达式,所以你必须这样做。 =)
第一组应以可选的双斜杠开头。我用
item..subsub_element(@key = string)
。此处(?://)?
表示不应捕获此部分,最后?:
使该组成为可选项。
然后,有一些单词,包含字符和下划线,按点分组。一个这样的单词(带有尾随点)可以表示为?
。我认为你实际使用的[a-zA-Z_]+\.{0,2}
是\w
的捷径。它不代表一个单词,而是一个“单词字符”。
最后一个表达式可能会多次出现,因此第一个组的捕获表达式看起来像
[a-zA-Z0-9_]
对于括号中的部分,可以使用((?://)?(?:[a-zA-Z_]+\.{0,2})+)
,这意味着一个开放括号(转义,因为它具有特殊含义,后跟任意数量的非括号(未转义,因为它没有在一个字符类中的特殊含义),然后是一个结束括号。
结合\([^)]*\)
和^
分别标记行的开头和结尾,我们到达
$
如果我误解了您的要求,并需要帮助,请在评论中提问。
答案 2 :(得分:0)
你的模式有很多问题:
/{2}?
:您认为?
在这里意味着什么?因为如果您认为/{2}
是可选的,那就错了。相反,?
是{2}
重复的不情愿修饰符。也许像(?:/{2})?
这样的东西就是你想要的。
[\w+_*]
:您认为+
和*
在这里意味着什么?因为如果你认为它们代表重复,那你就错了。这是一个字符类定义,+
和*
字面意思是字符+
和*
。也许你打算......实际上我不确定你的意图。
这是试图猜测你的规范是什么:
String PART_REGEX =
"(word)(?:<<@(word) = (word)>>)?"
.replace("word", "\\w+")
.replace(" ", "\\s*")
.replace("<<", "\\(")
.replace(">>", "\\)");
Pattern entirePattern = Pattern.compile(
"(?://)?part(?:\\.{1,2}part)*"
.replace("part", PART_REGEX)
);
Pattern partPattern = Pattern.compile(PART_REGEX);
然后我们可以按如下方式测试它:
String[] tests = {
"item.sub_element.subsubelement(@key = string)",
"item..subsub_element(@key = string)",
"//subsub_element(@key = string)",
"item(@key = string)",
"one.dot",
"two..dots",
"three...dots",
"part1(@k1=v1)..part2(@k2=v2)",
"whatisthis(@k=v1=v2)",
"noslash",
"/oneslash",
"//twoslashes",
"///threeslashes",
"//multiple//double//slashes",
"//multiple..double..dots",
"..startingwithdots",
};
for (String test : tests) {
System.out.println("[ " + test + " ]");
if (entirePattern.matcher(test).matches()) {
Matcher part = partPattern.matcher(test);
while (part.find()) {
System.out.printf(" [%s](%s => %s)%n",
part.group(1),
part.group(2),
part.group(3)
);
}
}
}
以上版画:
[ item.sub_element.subsubelement(@key = string) ]
[item](null => null)
[sub_element](null => null)
[subsubelement](key => string)
[ item..subsub_element(@key = string) ]
[item](null => null)
[subsub_element](key => string)
[ //subsub_element(@key = string) ]
[subsub_element](key => string)
[ item(@key = string) ]
[item](key => string)
[ one.dot ]
[one](null => null)
[dot](null => null)
[ two..dots ]
[two](null => null)
[dots](null => null)
[ three...dots ]
[ part1(@k1=v1)..part2(@k2=v2) ]
[part1](k1 => v1)
[part2](k2 => v2)
[ whatisthis(@k=v1=v2) ]
[ noslash ]
[noslash](null => null)
[ /oneslash ]
[ //twoslashes ]
[twoslashes](null => null)
[ ///threeslashes ]
[ //multiple//double//slashes ]
[ //multiple..double..dots ]
[multiple](null => null)
[double](null => null)
[dots](null => null)
[ ..startingwithdots ]