R 如何匹配只包含任意顺序和任意数字的字符集的字符串?
我似乎不知道如何匹配只包含%,和§,并且以任何顺序和重复次数的字符串:R 如何匹配只包含任意顺序和任意数字的字符集的字符串?,r,regex,R,Regex,我似乎不知道如何匹配只包含%,和§,并且以任何顺序和重复次数的字符串: str <- c("%#", "#%%§§#", "§%5x#yz", "%#§", "ab§", "!#%§") 只是最后一场比赛!%§不正确,因为字符串不仅包含字符集。我明白了为什么grepl会匹配这个字符串:因为最后三个字符确实是字符集。因此,剩下的问题是如何限制字符集的匹配。我尝试使用锚定“
str <- c("%#", "#%%§§#", "§%5x#yz", "%#§", "ab§", "!#%§")
只是最后一场比赛!%§不正确,因为字符串不仅包含字符集。我明白了为什么grepl会匹配这个字符串:因为最后三个字符确实是字符集。因此,剩下的问题是如何限制字符集的匹配。我尝试使用锚定“^”和$,但没有找到任何匹配项:
grepl("^(?=[§#]*%)(?=[§%]*#)(?=[%#]*§)$", str, perl = T)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
这里的解决方案是什么?您可以使用:
^?=.*%?=.*?=.*§[%§]+$
诀窍是确保字符串中的所有字符都是允许的字符。我们通过在Lookaheads之外使用^[%§]+$来实现
细分:
^-字符串的开头。
?=.*-一个积极的前瞻,以确保''%1!''字符存在。
?=.*-正向前瞻,以确保角色存在。
?=.*.§-一个积极的前瞻,以确保“§”字符存在。
[%§]+-匹配字符类中的一个或多个字符。
$-字符串的结尾。
另一种方法:通过前瞻确保字符串仅由三个字符组成,然后使用捕获组和反向引用匹配包含三个不同字符的字符串,反向引用限制为负lookahead:
^(?=[%§#]+$)(.).*(?!\1)(.).*(?!\1|\2).
看
:
str不,匹配必须包括所有三个字符,并且不超过这三个字符是的,当然!就这样!然后^?=[§]*%?=[§%]*?=[%]*§[%§]+$也可以工作,但您的显然更优雅,更不冗长。@Chris是的,但因为我们在字符类中使用了允许的字符。在Lookaheads中应该足够了。@ChrisRuehlemann如果字符串可以是任意的,请使用您的方法。仅当输入字符串始终只有%§且不太长时才使用此。*方法。@ChrisRuehlemann如果字符串可能来自不同长度的用户,则?=[%§]+$lookahead将在触发那些lookaheads/backreferences之前更快地过滤出无效字符串。
^(?=[%§#]+$)(.).*(?!\1)(.).*(?!\1|\2).
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
[%§#]+ any character of: '%', '§', '#' (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
$ before an optional \n, and the end of
the string
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
. any character except \n
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
\1 what was matched by capture \1
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
( group and capture to \2:
--------------------------------------------------------------------------------
. any character except \n
--------------------------------------------------------------------------------
) end of \2
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
\1 what was matched by capture \1
--------------------------------------------------------------------------------
| OR
--------------------------------------------------------------------------------
\2 what was matched by capture \2
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
. any character except \n