我正在尝试在一个字符子集中匹配一个字符,其中匹配字符的任一侧都可以是任何字符。
这里是一个例子:
{{ SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS }}
相对于上述情况,我想匹配{{和}}之间带有短划线“-”的任何内容。
到目前为止,我的正则表达式模式是:(?<={{)(.*?-.*?)(?=}})
但这会为返回的整个测试字符串创建一个匹配项:
SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS
有人能看到我所缺少的吗?我了解为什么我的正则表达式无法按预期运行,但无法解决该问题。
谢谢
答案 0 :(得分:3)
您可以将此正则表达式与负前瞻和捕获组配合使用:
({{(?:(?!{{|}})[^-])*)-(.*?}})
RegEx详细信息:
(
:开始捕获组
{{
:匹配{{
(?:
:启动非捕获组
(?{{|!}})
:否定前瞻,断言我们在下一个位置没有{{
和}}
[^-]
:匹配除连字符以外的任何字符)*
:结束非捕获组。 *
匹配该组的0+个实例)
:结束捕获组-
:匹配文字连字符(.*?}})
:匹配其余字符串,直到}}
,然后匹配}}
并将其捕获到第二个捕获组中答案 1 :(得分:3)
使用
import re
s = '{{ SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS }}'
print([x.strip() for x in re.findall(r'{{(.*?)}}', s) if '-' in x])
// -> ['BGP-AS']
详细信息
{{...}}
的正则表达式提取{{(.*?)}}
之间的所有匹配项(请注意,re.findall
将仅返回捕获的替换,该值与(.*?)
匹配)-
)内的条件保留与其中if '-' in x
的匹配项.strip()
删除尾随/前导空格单个正则表达式方法(请注意,它可能会降低效率):
re.findall(r'{{\s*((?:(?!{{|}})[^-])*-.*?)\s*}}', s)
请参见Python demo
详细信息
{{
-{{
\s*
-超过0个空格((?:(?!{{|}})[^-])*-.*?)
-捕获组1(re.findall
返回的内容):
(?:(?!{{|}})[^-])*
-一个tempered greedy token匹配0次以上的任何非连字符,不会启动{{
和}}
子字符串-
-连字符.*?
-任意0个以上的字符(LF除外),尽可能少\s*
-超过0个空格}}
-}}
。请参见regex demo
答案 2 :(得分:0)
您可以使用以下模式:{{(.*?)}}
。
.*?
非贪婪地匹配任何字符流。
(...)
创建一个捕获组,因此re.findall
产生括号的内部。
要检查匹配项是否包含'-'
,使用in
可能会更简单。
import re
def tokenize(s):
return [w.strip() for w in re.findall('{{(.*?)}}', s) if '-' in w]
print(tokenize('{{ SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS }}'))
['BGP-AS']