我正在努力解决这个正则表达式难题,但这超出了我的专业知识......
我有这样的字符串:
字符串1:
Interface123|HostVienna ~ Tunnel22 ~ CustomerA ~ ServiceA ~ Vienna, Street 10|HostAmsterdam ~ Interface123 ~ CustomerB ~ ServiceA ~ Amsterdam, Street 40|HostSarajevo ~ Interface12 ~ CustomerC ~ ServiceA ~ Sarajevo, Street 1040
字符串2
Interface123|HostAmsterdam ~ Interface123 ~ CustomerB ~ ServiceA ~ Amsterdam,Street 40
我正在尝试制作一个可以匹配从字符串开头到“|”的所有内容的正则表达式(单词)并使用那个匹配我试图找到由“|”分隔的字符串包含那个词。在我的例子中,这个词是Interface123
。
从上面的任何一个例子中,结果应该是:
HostAmsterdam ~ Interface123 ~ CustomerB ~ ServiceA ~ Amsterdam,Street 40
纯正的正则表达式有可能吗?
这可以通过regexp返回引用实现,但并非每个实现都支持它们。就像是:
^([^|]+)\|(?:[^|]*\|)*?([^|]*\1[^|]*)
第二组将捕捉您需要的东西。
说明:^([^|]+)\|
捕获您的关键字,(?:[^|]*\|)*?
匹配由'|'
包围的零个或多个字符串没有关键字,([^|]*\1[^|]*)
匹配您最终需要的。
/^([^|]+)\|(?:[^|]+\|)*?\K[^|]*\b\1\b[^|]*/
捕获针很重要,并且在搜索下一次出现时至少使用wordboundaries。
此外,重要的是启用匹配作为字符串中的第一个,中间或最后一个数据集。这是(?:[^|]+\|)*?
的重要性
但是:Kua zxsw指出
分解:
https://regex101.com/r/7lMwZf/5
这是一个似乎有效的模式:
^ # start of string
([^|]+)\| # capture needle then match first delimiting pipe
(?:[^|]+\|)*? # match zero or more "sets of data"
\K[^|]*\b\1\b[^|]* # forget previously matched characters with \K, then match set of data containing the needle until the end of string or first encountered pipe
这使用淬火点来匹配你想要的字符串片段,包含(?<=\||^)((?:(?!\|).)*Interface123.*?)(?=\||$)
。这是一个简短的解释:
Interface123
(?<=\||^) assert that what is prior is either pipe or the start of the string
((?:(?!\|).)* consume anything so long is it is NOT pipe
Interface123.*? match 'Interface123` followed by anything up to
(?=\||$) assert that what follows is either pipe or the end of the string
这个答案使用了外观,但根据您的注释,您的正则表达式风格与Perl兼容,这应该不是问题。