問題のドメインに関して、未回答の質問がいくつかあります。それはさておき、正の一致の質問で提供されたサンプルデータと負の一致のいくつかの追加のサンプルデータを含む次のデータを使用しましょう(私は使用していR version 2.14.1 (2011-12-22)
ます):
x <- c("140,000 mostly freeway miles", "173k commuter miles. ", "154K(all highway) miles", "1,24 almost but not mostly freeway miles", "1,2,3,4K MILES")
1,2,3,4K MILES
1-3 words apart
質問はnearasを定義し、これには「near words」がゼロであるため、は負の一致として追加されます。
以下を使用すると...
sub('[\\d,]+k?\\s+(([^\\s]+\\s+){1,3})miles', '\\1', x, ignore.case = TRUE, perl = TRUE)
... 我々が得る:
[1] "mostly freeway "
[2] "commuter . "
[3] "154K(all highway) miles"
[4] "1,24 almost but not mostly freeway miles"
[5] "1,2,3,4K MILES"
おそらくあなたが望む結果ではありません。データは正規化されていないため、非常に複雑になる正規表現パターンを使用する必要があります。ジャスティンが彼の答えで示唆しているように、clean up the data first then do some simpler matching
。
次のようにデータを正規化できます。
y <- gsub('\\pP+', ' ', x, perl = TRUE)
y <- gsub('\\s+', ' ', y, perl = TRUE)
y <- gsub('^\\s+|\\s+$', '', y, perl = TRUE)
y <- gsub('(\\d)\\s(?=\\d)', '\\1\\2', y, perl = TRUE)
詳細については、以下のリファレンスを参照してください。これは基本的に句読点を削除し、単語が単一のスペースで区切られていることを確認することです。これにより、次のことが可能になりますy
。
[1] "140000 mostly freeway miles"
[2] "173k commuter miles"
[3] "154K all highway miles"
[4] "124 almost but not mostly freeway miles"
[5] "1234K MILES"
次に、探しているものと一致しない行を削除します。
y <- sub('^(?!\\d+k?\\s((?!miles)[^\\s]+\\s){1,3}miles).*$', '', y, ignore.case = TRUE, perl = TRUE)
y
[1] "140000 mostly freeway miles" "173k commuter miles"
[3] "154K all highway miles" ""
[5] ""
最後に、「近い単語」を取得します。
y <- sub('^\\d+k?\\s((?!miles)[^\\s]+(\\s(?!miles)[^\\s]+){0,2})\\smiles', '\\1', y, ignore.case = TRUE, perl = TRUE)
y
[1] "mostly freeway" "commuter" "all highway" ""
[5] ""
データを正規化するためのより簡単な方法はおそらくありますが、これにより、正規表現の例をいくつか試してみることができます。
詳細については、以下を参照してください。