首先,我是regex的初学者。我有一个看起来像这样的字符串:
my_folder/foo.xml::someextracontent
my_folder/foo.xml::someextracontent
another_folder/foo.xml::someextracontent
my_folder/bar.xml::someextracontent
my_folder/bar.xml::someextracontent
my_folder/hello.xml::someextracontent
我想返回my_folder
中的唯一XML文件。因此正则表达式将返回:
my_folder/foo.xml
my_folder/bar.xml
my_folder/hello.xml
我看过Extract All Unique Lines,它很接近我的需求,但我不确定从那里去哪里。
我最接近的尝试是(?sm)(my_folder\/.*?.xml)(?=.*\1)
,它获得了所有重复项,但是我想要相反的选择,所以我尝试进行负向前瞻而不是(?sm)(my_folder\/.*?.xml)(?!.*\1)
,但是捕获组完全错误。
我的正则表达式在这里缺少什么?这是正则表达式的链接:https://regex101.com/r/ggY2RB/1
答案 0 :(得分:1)
This RegEx可能会帮助您找到所需的唯一字符串:
/(\w+\/\w+\.xml)(?![\s\S]*\1)/s
如果您只想匹配my_folder
,则可以尝试this:
/(\my_folder\/\w+\.xml)(?![\s\S]*\1)/s
答案 1 :(得分:1)
除了使用正向前行(?=
来获取唯一的字符串,还可以使用负向前行(?!
来断言右边的内容不是您在第1组中捕获的内容。
在您的模式中,您正在使用(?s)
使点与换行符匹配,并使用非贪心的点开始.*?
,但是您也可能使用与换行符或反斜杠匹配的否定字符类
如果该文件夹还可以包含嵌套文件夹,则可以使用一种模式,该模式重复0+乘以1+空格字符,后跟一个正斜杠。
(?s)(my_folder/(?:[^/\n]+/)*[^/\n]+\.xml)::(?!.*\1)
(?s)
(
捕获组
my_folder/
字面上匹配(?:[^/\n]+/)*
重复0次以上,而不是正斜杠或换行符,后跟正斜杠[^/\n]+\.xml
匹配1+或正斜杠或换行符,后跟.xml )
关闭捕获组::(?!.*\1)
匹配::
,然后断言右边的内容不包含第1组中捕获的内容在Java中
String regex = "(?s)(my_folder/(?:[^/\\n]+/)*[^/\\n]+\\.xml)::(?!.*\\1)";