web-dev-qa-db-ja.com

gsubを使用して文字列に英数字とスペースのみを保持する

英数字、特殊文字、非UTF-8文字を含む文字列があります。特殊文字とutf-8以外の文字を削除したい。

これが私が試したものです:

gsub('[^0-9a-z\\s]','',"�+ Sample string here =�{�>E�BH�P<]�{�>")

ただし、これにより特殊文字(句読点+非utf8)は削除されますが、出力にはスペースがありません。

gsub('/[^0-9a-z\\s]/i','',"�+ Sample string here =�{�>E�BH�P<]�{�>")

結果にはスペースがありますが、まだutf8以外の文字が残っています。

回避策はありますか?

上記のサンプル文字列の場合、出力は次のようになります。

9
lilipunk

これには、クラス[:alnum:]および[:space:]を使用できます。

sample_string <- "�+ Sample 2 string here =�{�>E�BH�P<]�{�>"
gsub("[^[:alnum:][:space:]]","",sample_string)
#> [1] "ï Sample 2 string here ïïEïBHïPïï"

または、PCREコードを使用して特定の文字セットを参照することもできます。

gsub("[^\\p{L}0-9\\s]","",sample_string, Perl = TRUE)
#> [1] "ï Sample 2 string here ïïEïBHïPïï"

どちらの場合も、まだそこにいる文字は文字と見なされることを明確に示しています。また、内部のEBHPはまだ文字であるため、交換する条件が正しくありません。すべての文字を保持するのではなく、A-Z、a-z、0-9を保持するだけです。

gsub("[^A-Za-z0-9 ]","",sample_string)
#> [1] " Sample 2 string here EBHP"

これにはまだEBHPが含まれています。本当に文字と数字のみを含むセクションを保持したい場合は、逆のロジックを使用する必要があります。必要なものを選択し、後方参照を使用してそれ以外のものをすべて置き換えます。

gsub(".*?([A-Za-z0-9 ]+)\\s.*","\\1", sample_string)
#> [1] " Sample 2 string here "

または、スペースで区切られていなくても文字列を検索する場合は、代わりにワード境界\\bを使用します。

gsub(".*?(\\b[A-Za-z0-9 ]+\\b).*","\\1", sample_string)
#> [1] "Sample 2 string here"

ここでは何が起きるのですか:

  • .*?は、少なくとも0回(*)は何でも(。)適合しますが、貪欲ではありません(?)これは、gsubがこのピースで可能な最小量に適合しようとすることを意味します。
  • ()の間のすべてが保存され、\\1による置換で参照できます
  • \\bは単語の境界を示します
  • この後には、少なくとも1回(+)、A〜Z、a〜z、0〜9、またはスペースの文字が続きます。特殊文字はコード表の大文字と小文字の間に含まれているため、そのようにする必要があります。したがって、A-zを使用すると、すべての特殊文字(UTF-8です!)が含まれます。
  • そのシーケンスの後、残りの文字列を削除するために少なくとも0回は何でもフィットします。
  • 正規表現で\\1と組み合わせて後方参照.*を使用すると、必要な部分だけが出力に残るようになります。
12
Joris Meys

ストリンガーは、POSIX文字クラスをサポートする別の正規表現エンジンを使用する場合があります。 :ascii:はクラスに名前を付けます。クラスは通常、大括弧[:asciii:]で囲む必要があり、外側の大括弧で囲みます。 [^は一致の否定を示します。

library(stringr)
str_replace_all("�+ Sample string here =�{�>E�BH�P<]�{�>", "[^[:ascii:]]", "")

結果は[1] "+サンプル文字列= {> EBHP <] {>"

0
Andrew Lavers