(跳过)(失败)使用 stringi 解析错误
(Skip)(Fail) Parse error with stringi
我是 reading/learning The Greatest Regex Trick Ever 我们说我们想要一些东西除非...使用 (*SKIP)(*FAIL)
。好的,所以我试了一下下面的玩具示例,它在 base R 中工作,但在 stringi 中有以下错误。我是否需要对 stringi 做一些不同的事情才能使语法正常工作?
x <- c("I shouldn't", "you should", "I know", "'bout time")
pat <- '(?:houl)(*SKIP)(*FAIL)|(ou)'
grepl(pat, x, perl = TRUE)
## [1] FALSE TRUE FALSE TRUE
stringi::stri_detect_regex(x, pat)
## Error in stringi::stri_detect_regex(x, pat) :
## Syntax error in regexp pattern. (U_REGEX_RULE_SYNTAX)
stringi
模块(以及 stringr
)与 ICU regex library 捆绑在一起,不支持 (*SKIP)(*FAIL)
动词(它们实际上仅受 PCRE 库支持).
由于您匹配的 ou
前面没有 h
,后面也没有 l
,您可以使用通常的环视:
(?<!h)ou(?!l)
> x <- c("I shouldn't", "you should", "I know", "'bout time")
> pat1 <- "(?<!h)ou(?!l)"
> stringi::stri_detect_regex(x, pat1)
[1] FALSE TRUE FALSE TRUE
我还可以在这里建议另一种方法。由于您的代码暗示您只想 return 一个布尔值,指示字符串中是否有 ou
而不是 houl
,您可以使用
stringi::stri_detect_regex(x, "^(?!.*houl).*ou")
详情
^
- 字符串的开头
(?!.*houl)
- 如果在字符串开头之后有 0+ 个字符而不是换行符,则匹配失败的否定前瞻尽可能多地后跟 houl
.*
- 0+ 换行字符以外的字符尽可能多
ou
- ou
子串。
有关 Lookahead and Lookbehind Zero-Length Assertions 的更多详细信息。
请注意,在 ICU 中,lookbehind 不能包含未知宽度的模式,但是,lookbehind 中的限制量词是受支持的。所以,在 stringi
中,如果你想匹配任何包含 ou
且左边某处没有以 s
开头的单词,你可以使用
> pat2 <- "(?<!s\w{0,100})ou"
> stringi::stri_detect_regex(x, pat2)
[1] FALSE TRUE FALSE TRUE
如果 (?<!s\w{0,100})
constrained-width lookbehind 匹配失败,如果 ou
前面是 s
后跟 0 到 100 字母数字或下划线字符。
我是 reading/learning The Greatest Regex Trick Ever 我们说我们想要一些东西除非...使用 (*SKIP)(*FAIL)
。好的,所以我试了一下下面的玩具示例,它在 base R 中工作,但在 stringi 中有以下错误。我是否需要对 stringi 做一些不同的事情才能使语法正常工作?
x <- c("I shouldn't", "you should", "I know", "'bout time")
pat <- '(?:houl)(*SKIP)(*FAIL)|(ou)'
grepl(pat, x, perl = TRUE)
## [1] FALSE TRUE FALSE TRUE
stringi::stri_detect_regex(x, pat)
## Error in stringi::stri_detect_regex(x, pat) :
## Syntax error in regexp pattern. (U_REGEX_RULE_SYNTAX)
stringi
模块(以及 stringr
)与 ICU regex library 捆绑在一起,不支持 (*SKIP)(*FAIL)
动词(它们实际上仅受 PCRE 库支持).
由于您匹配的 ou
前面没有 h
,后面也没有 l
,您可以使用通常的环视:
(?<!h)ou(?!l)
> x <- c("I shouldn't", "you should", "I know", "'bout time")
> pat1 <- "(?<!h)ou(?!l)"
> stringi::stri_detect_regex(x, pat1)
[1] FALSE TRUE FALSE TRUE
我还可以在这里建议另一种方法。由于您的代码暗示您只想 return 一个布尔值,指示字符串中是否有 ou
而不是 houl
,您可以使用
stringi::stri_detect_regex(x, "^(?!.*houl).*ou")
详情
^
- 字符串的开头(?!.*houl)
- 如果在字符串开头之后有 0+ 个字符而不是换行符,则匹配失败的否定前瞻尽可能多地后跟houl
.*
- 0+ 换行字符以外的字符尽可能多ou
-ou
子串。
有关 Lookahead and Lookbehind Zero-Length Assertions 的更多详细信息。
请注意,在 ICU 中,lookbehind 不能包含未知宽度的模式,但是,lookbehind 中的限制量词是受支持的。所以,在 stringi
中,如果你想匹配任何包含 ou
且左边某处没有以 s
开头的单词,你可以使用
> pat2 <- "(?<!s\w{0,100})ou"
> stringi::stri_detect_regex(x, pat2)
[1] FALSE TRUE FALSE TRUE
如果 (?<!s\w{0,100})
constrained-width lookbehind 匹配失败,如果 ou
前面是 s
后跟 0 到 100 字母数字或下划线字符。