所以,我正在努力捕捉字符串包含的那种“语言”片段:
语言代码段位于()
内,并且是En,Fr,De,Es,It
示例:
File (En,Fr,De,Es,It).doc <== should match all 5 languages
File (En,Fr) (Required).doc <== should match `En` and `Fr`
File (Enfoo,Fr).doc <== should match only `Fr`
File (E,Fr).doc <== should match only `Fr`
我当前的正则表达式:
((\(|,)En(\)|,))|((\(|,)Fr(\)|,))|((\(|,)De(\)|,))|((\(|,)Es(\)|,))|((\(|,)It(\)|,))
这是什么意思:
((\(|,) <== either starts with `open parenthesis` or `comma` (1)
En <== the language (2)
(\)|,)) <== either ends with `close parenthesis` or `comma` (3)
然后我只用正则表达式OR
(|)
您可以看到问题:regexr.com/3ev6p如果有第二个语言代码段Fr
,它将无法满足正则表达式(1)
,因为第一个语言代码段{{1正在捕获/占用En
或open parenthesis
,导致第二语言代码段comma
不匹配...
你们知道如何处理完全捕获所有语言片段吗?我打算用PHP的Fr
来获取所有这些。希望有人可以提供帮助。
谢谢!
答案 0 :(得分:3)
你使用的正则表达式使用逗号围绕语言代码。这意味着,在找到匹配后,索引在逗号后面,并且因为不能匹配,所以正则表达式引擎会跳过该逗号之后的语言。
为了匹配此类重叠匹配,可以使用以下内容:
(?<=[(,])(En|Fr|De|Es|It)(?=[,)])
^^^^^^^^^ ^^^^^^^^
请参阅this regex demo。
(?<=[(,])
是一个积极的观察,需要在语言代码之前使用,
或(
,而(?=[,)])
是一个需要逗号或{{1}的正面预测在语言代码的右边,但是没有使用逗号/括号,它在下一次迭代期间仍然需要匹配。
此处可能的另一种解决方案是使用单词边界(如评论中所述)。单词边界有助于匹配整个单词。
)
请参阅regex demo
答案 1 :(得分:1)
这应该匹配所有:
(?<=,|\()(\w\w)(?=,|\))
陪同preg_match_all
应该做的工作。
说明:
就是这样。 :)
问候。