4

正規表現を使って、近くにある単語をどのように選択するのか疑問に思いました。たとえば、次のフレーズから数字とマイルという単語を選択したいと思います。

"140,000 mostly freeway miles" 
"173k commuter miles. "       
"154K(all highway) miles

真ん中のオプションの単語を入力する方法がわかりません:

[0-9]+ ???? miles

* nearは、1〜3語離れていると定義できます。それを指摘してくれてありがとう。

4

4 に答える 4

3

これがの答えですR。他の答えは、いくつかの変更で機能する可能性があります。ほとんどの場合、それらには「ダブルエスケープ」が必要であり、対関数regexprとを使用する必要がありますregmatches

x=c("140,000 mostly freeway miles" ,"173k commuter miles. " ,"154K(all highway) miles")


gsub('([[:digit:][:punct:]k]+).*(miles).*', 
     '\\1 \\2', 
     x,
     ignore.case=TRUE)

# [1] "140,000 miles" "173k miles"    "154 miles"    

これは、グループ1のグループ番号の句読点またはakを示しています。これに続くものは何でもかまいません。次に、これにマイルという単語であるグループ2が続き、その後に他のものが続きます。

「通常の」正規表現構文を使用することもできます。

gsub('([0-9,k]+).*(miles).*', 
     '\\1 \\2', 
     x,
     ignore.case=TRUE)

ただし、最初にデータをクリーンアップしてから、より簡単なマッチングを行います。(たとえばtolower、句読点を削除します)。

于 2012-11-21T20:15:37.370 に答える
1

問題のドメインに関して、未回答の質問がいくつかあります。それはさておき、正の一致の質問で提供されたサンプルデータと負の一致のいくつかの追加のサンプルデータを含む次のデータを使用しましょう(私は使用してい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 MILES1-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] ""

データを正規化するためのより簡単な方法はおそらくありますが、これにより、正規表現の例をいくつか試してみることができます。

詳細については、以下を参照してください。

于 2012-11-22T16:08:12.043 に答える
0

この正規表現を使用する\d+([.,]\d+)?(?=.*?miles)

于 2012-11-21T19:23:23.250 に答える
0

これはまだ少しあいまいですが、すべてをスペースで区切られた「単語」として定義するとします。したがって、1〜3語の場合は、数字とmiles:の間に2〜4個のスペースが必要です(実際、最初の単語はオプションにします。最後の例を参照してください)。

\d[\d,.]*k?\s*(\S+\s+){1,3}miles

kとの両方に一致させるには、この正規表現で大文字と小文字を区別しないようにする必要があることに注意してくださいK

また、数字の部分は確かに改善される可能性があることに注意してください。これは、最初の桁だけを取り、有効な数値形式であるかどうかに関係なく、できるだけ多くの桁、コンマ、およびピリオドを含みます。

于 2012-11-21T19:48:13.823 に答える