5

私は、...を使用しない限り、何かが欲しいと言う場所で、これまでで最高の正規表現のトリックを読んだり学んだりして(*SKIP)(*FAIL)いました。わかりましたので、以下のおもちゃの例をスピンしてみました。ベース 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)
4

1 に答える 1

2

stringiモジュール (およびstringr同様) はICU 正規表現ライブラリにバンドルされており、動詞(*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

ここで別のアプローチを提案することもできます。ouあなたのコードは、文字列の中にあるがそうではないかどうかを示すブール値を返したいだけであることを意味するので、houl使用することができます

stringi::stri_detect_regex(x, "^(?!.*houl).*ou")

別の正規表現のデモを見る

詳細

  • ^- 文字列の開始
  • (?!.*houl)- 文字列の開始直後に改行文字以外の 0+ 文字ができるだけ多く続く場合に一致に失敗する否定先読みhoul
  • .*- 改行文字以外の 0+ 文字はできるだけ多く
  • ou-ou部分文字列。

Lookahead および Lookbehind Zero-Length Assertions の詳細。

ICU では、後読みに未知の幅のパターンを含めることはできませんが、後読み内の限定量指定子はサポートされていることに注意してください。したがって、 でstringi、 を含む任意の単語に一致させたい場合は、左のどこかがou前にない場合、次を使用できます。s

> pat2 <- "(?<!s\\w{0,100})ou"
> stringi::stri_detect_regex(x, pat2)
[1] FALSE  TRUE FALSE  TRUE

(?<!s\\w{0,100}) 制約付き幅の後読みは、 0 ~ 100 文字の英数字またはアンダースコア文字ouが前にある場合、一致に失敗します。s

于 2016-05-26T22:28:20.833 に答える