web-dev-qa-db-ja.com

R-正規表現:パターンで始まらない文字列に一致する

正規表現を使用して、文字列が特定のパターンで始まらないかどうかを確認したいと思います。 _[^_を使用して特定の文字をブラックリストに登録することはできますが、パターンをブラックリストに登録する方法がわかりません。

_> grepl("^[^abc].+$", "foo")
[1] TRUE
> grepl("^[^abc].+$", "afoo")
[1] FALSE
_

grepl("^[^(abc)].+$", "afoo")のようなことをしてTRUEを取得したいのですが、つまり、文字列がabcシーケンスで始まらない場合に一致させたいのです。

この投稿 を認識しており、_Perl = TRUE_も使用しようとしましたが、成功しませんでした。

_> grepl("^((?!hede).)*$", "hede", Perl = TRUE)
[1] FALSE
> grepl("^((?!hede).)*$", "foohede", Perl = TRUE)
[1] FALSE
_

何か案は?

18
aL3xa

ええ。ゼロ幅の先読みを他の親の/外側/に置きます。それはあなたにこれを与えるはずです:

_> grepl("^(?!hede).*$", "hede", Perl = TRUE)
[1] FALSE
> grepl("^(?!hede).*$", "foohede", Perl = TRUE)
[1] TRUE
_

私はあなたが望むものだと思います。

または、文字列全体をキャプチャする場合は、^(?!hede)(.*)$^((?!hede).*)$の両方が同等で受け入れられます。

24
Dan

私は次の特別なケースで立ち往生したので、私は共有したいと思いました...

正規表現のインスタンスが複数あるが、それでも最初のセグメントのみが必要な場合はどうなりますか?

どうやらあなたは特定の Perlワイルドカード修飾子 で検索の暗黙の貪欲さをオフにすることができます

処理したい文字列が

myExampleString = paste0(c(letters[1:13], "_", letters[14:26], "__",
                           LETTERS[1:13], "_", LETTERS[14:26], "__",
                           "laksjdl", "_", "lakdjlfalsjdf"),
                         collapse = "")
myExampleString

"abcdefghijklm_nopqrstuvwxyz__ABCDEFGHIJKLM_NOPQRSTUVWXYZ__laksjdl_lakdjlfalsjd"

そして、最初の"__"の前の最初のセグメントだけが必要でした。この例の文字列では単一アンダースコアが許容される非区切り文字であるため、"_"を単純に検索することはできません。

以下は機能しません。代わりに、デフォルトの貪欲さのために、最初のの2番目のセグメントが表示されます(ただし、前向きなため、3番目ではありません)。

gsub("^(.+(?=__)).*$", "\\1", myExampleString, Perl = TRUE)

"abcdefghijklm_nopqrstuvwxyz__ABCDEFGHIJKLM_NOPQRSTUVWXYZ"

しかし、これは機能します

gsub("^(.+?(?=__)).*$", "\\1", myExampleString, Perl = TRUE)

"abcdefghijklm_nopqrstuvwxyz"

違いは、(Perl)正規表現のワイルドカード"?"の後のgreedy-modifier".+"です。

2
Paul McMurdie

現在(数年後)stringrパッケージには別の可能性があります。

library(stringr)

str_detect("dsadsf", "^abc", negate = TRUE)
#> [1] TRUE

str_detect("abcff", "^abc", negate = TRUE)
#> [1] FALSE

reprexパッケージ (v0.3.0)によって2020-01-13に作成されました

0
pasipasi