我有一些字符串可以通过RegEx匹配。我们有一个java应用程序,它从配置文件中读取正则表达式,并接受两组字符串,其中的数量在同一个配置中指定。
E.g。
CustomAction.523274ca945f.dialogLabel=Executing Custom Code...
将与
匹配(?m)^(?!#)\s*(\S*)\s*=\s*(\S*.*)
我需要的是选择第一组“CustomAction.523274ca945f.dialogLabel
”并在中间排除随机字符串,这样我最终会得到类似“CustomAction.dialogLabel
”或“CustomAction..dialogLabel
”的内容任何其他组合,但随机字符串。
我没有我正在使用的java应用程序的源代码。这是一个应用程序,我可以创建一个配置文件,我在其中指定一个模式和两个组,应用程序选择它们
pattern: (?m)^(?!#)\\s*([^.=\\s]*)\\.(?:[^.=\\s]*\\.)?([^.=\\s]*)\\s*=\\s*(.*?)\\s*$ key_group: 1 value_group: 2
我只能为每个键指定一个组,每个值指定一个组。根据这种模式,app选择key_group作为键,value_group作为它的值。
我不希望垃圾在中间,因为它是随机的,每次都会改变密钥。
答案 0 :(得分:2)
两种方法;首先假设你的财产是三个项目,用你的第一个(\ S *)简单替换:
(\S+?)\.\S+?\.(\S+)
注意我也将*更改为+,因为将“..”作为属性的一部分是没有意义的,我也使用了非贪婪的限定符,但没有它们它仍然可以正常工作。然后,您可以使用适当的组编号重建调整后的属性。第二种方法假设您的随机字符串是十六进制数字(它看起来像是),并且该属性的非随机部分不包含数字:
((?:\S+.)*)(?:[0-9A-Fa-f]+.)?((?:\S+.?)+)
所以第一组应该在随机数(包括尾随点)之前拾取所有内容,第二组将吃随机数,然后第三组将匹配剩余的字符串(或者如果没有随机数部分则整个事情)。
修改强>
使用更新的问题描述并且仅匹配两个组我的答案是不可能的。在正则表达式中,没有机制来“擦除”匹配的一部分。从问题定义中,不包括的密钥部分位于其他文本的中间,即要匹配的一般模式是:
((a)(?:b)(c))
由于我们不能预处理或后处理“b”将始终是包含a和c的较大匹配组的一部分,因此它是不匹配组的事实不会影响较大的组。 / p>
答案 1 :(得分:0)
规范不是很清楚,但这是我要假设的:
#
是评论.
分隔
=
,然后是“值”.
和=
是至少在“价值”部分之前的特殊标记,然后一切顺利那么也许这种模式就像这样:
String text =
" some.stuff.here = blah blah \n" +
" awesome.key = { level = 10 } \n" +
"# awesome.key = { level = 11 } \n" +
" awesome..key = { level = 12 } \n" +
" !@#$.)(*&.$%& = a=b=c.d=f ";
Pattern p = Pattern.compile(
"(?m)^(?!#) (key)@(?:key@)?(key) = (value) $"
.replace("@", "\\.")
.replace(" ", "\\s*")
.replace("key", "[^.=\\s]*")
.replace("value", ".*?")
);
Matcher m = p.matcher(text);
while (m.find()) {
System.out.printf("%s.%s => [%s]%n",
m.group(1),
m.group(2),
m.group(3)
);
}
打印:
some.here => [blah blah]
awesome.key => [{ level = 10 }]
awesome.key => [{ level = 12 }]
!@#$.$%& => [a=b=c.d=f]
注意replace
方法生成最终的正则表达式模式;它用于增强整体大图“模式”的可读性