111  実践1 数字の指定

library(tidyverse)

それでは、正規表現を実際に利用していってみましょう。この正規表現、多分、このコースでもかなりとっつきにくい部類に入りますのですんなり理解できなくても問題ありませんわからないところがあれば、私の解説方法が悪いので、是非Q&Aで質問してください。

それでは、はじめていきましょう。

正規表現とは文字列をパターンでひっかける手法です。

正規表現を完全にマスターすることは、本コースの目的ではありません。「汚いデータ」でよくある問題を解決するための最低限をお伝えすることを目的としています。

また、正規表現を利用しないで解決できる問題は可能な限りそっちを利用することが良いかもしれません。

まずvecという文字列ベクトルを作成します。

vec <- c("1","120","34.3","ab123", 
         "5b","6 5","7","b","ac4235432",
         "45.3mg/dl","abc500ml 3unit 3:40AM",
         "^ is start.",
         "this sign($) represents end.", "....")

vec
 [1] "1"                            "120"                         
 [3] "34.3"                         "ab123"                       
 [5] "5b"                           "6 5"                         
 [7] "7"                            "b"                           
 [9] "ac4235432"                    "45.3mg/dl"                   
[11] "abc500ml 3unit 3:40AM"        "^ is start."                 
[13] "this sign($) represents end." "...."                        

このvecの中に”1”という文字が含まれているかどうかを調べたければ、str_view()を使います。

str_view(vec,"1")
[1] │ <1>
[2] │ <1>20
[4] │ ab<1>23

このようにstr_viewは、ベクトルの中に指定した文字が含まれているかどうかを調べて見ることができる関数です。

str_viewは、str_view(<ベクトル,<正規表現>)という形で指定する関数となっており、“1”も立派な正規表現です。

これだけだと正規表現のメリットである文字列を塊として扱うという実感がわきにくいと思いますので、複数の文字列をひっかけてみましょう。

複数の文字列は、四角括弧の中に羅列することで表すことができて、“[1234]”のように書きます。

str_view(vec,"[1234]")
 [1] │ <1>
 [2] │ <1><2>0
 [3] │ <3><4>.<3>
 [4] │ ab<1><2><3>
 [9] │ ac<4><2><3>5<4><3><2>
[10] │ <4>5.<3>mg/dl
[11] │ abc500ml <3>unit <3>:<4>0AM

はい。このように、“1”か”2”か”3”か”4”かいずれかの文字を含む要素をひっかけることができています。

str_view(vec,"[1234]")
 [1] │ <1>
 [2] │ <1><2>0
 [3] │ <3><4>.<3>
 [4] │ ab<1><2><3>
 [9] │ ac<4><2><3>5<4><3><2>
[10] │ <4>5.<3>mg/dl
[11] │ abc500ml <3>unit <3>:<4>0AM
str_view(vec,"[0123456789]")
 [1] │ <1>
 [2] │ <1><2><0>
 [3] │ <3><4>.<3>
 [4] │ ab<1><2><3>
 [5] │ <5>b
 [6] │ <6> <5>
 [7] │ <7>
 [9] │ ac<4><2><3><5><4><3><2>
[10] │ <4><5>.<3>mg/dl
[11] │ abc<5><0><0>ml <3>unit <3>:<4><0>AM

尚、数字は特別な書き方があって、[0123456789] は

str_view(vec,"[0-9]")
 [1] │ <1>
 [2] │ <1><2><0>
 [3] │ <3><4>.<3>
 [4] │ ab<1><2><3>
 [5] │ <5>b
 [6] │ <6> <5>
 [7] │ <7>
 [9] │ ac<4><2><3><5><4><3><2>
[10] │ <4><5>.<3>mg/dl
[11] │ abc<5><0><0>ml <3>unit <3>:<4><0>AM
str_view(vec, "\\d")
 [1] │ <1>
 [2] │ <1><2><0>
 [3] │ <3><4>.<3>
 [4] │ ab<1><2><3>
 [5] │ <5>b
 [6] │ <6> <5>
 [7] │ <7>
 [9] │ ac<4><2><3><5><4><3><2>
[10] │ <4><5>.<3>mg/dl
[11] │ abc<5><0><0>ml <3>unit <3>:<4><0>AM
str_view(vec, "[:digit:]")
 [1] │ <1>
 [2] │ <1><2><0>
 [3] │ <3><4>.<3>
 [4] │ ab<1><2><3>
 [5] │ <5>b
 [6] │ <6> <5>
 [7] │ <7>
 [9] │ ac<4><2><3><5><4><3><2>
[10] │ <4><5>.<3>mg/dl
[11] │ abc<5><0><0>ml <3>unit <3>:<4><0>AM

等でもOKです。

ここまではすべて1文字引っかかるかを見ていますが、二文字引っかかったかを見るためには、

str_view(vec,"[0-9][0-9]")
 [2] │ <12>0
 [3] │ <34>.3
 [4] │ ab<12>3
 [9] │ ac<42><35><43>2
[10] │ <45>.3mg/dl
[11] │ abc<50>0ml 3unit 3:<40>AM
str_view(vec,"\\d\\d")
 [2] │ <12>0
 [3] │ <34>.3
 [4] │ ab<12>3
 [9] │ ac<42><35><43>2
[10] │ <45>.3mg/dl
[11] │ abc<50>0ml 3unit 3:<40>AM

のようにしてあげることで、一番最初の1単独はひっかからなくなっています。

「数字が連続する回数」での指定も可能で、{n,m}としてあげることで、n回以上、m回以下の連続する回数という指定ができます

str_view(vec,"[0-9]{2,4}")
 [2] │ <120>
 [3] │ <34>.3
 [4] │ ab<123>
 [9] │ ac<4235><432>
[10] │ <45>.3mg/dl
[11] │ abc<500>ml 3unit 3:<40>AM
str_view(vec,"\\d{2,4}")
 [2] │ <120>
 [3] │ <34>.3
 [4] │ ab<123>
 [9] │ ac<4235><432>
[10] │ <45>.3mg/dl
[11] │ abc<500>ml 3unit 3:<40>AM

1回以上の数字が連続した場合を調べるには

str_view(vec,"\\d+")
 [1] │ <1>
 [2] │ <120>
 [3] │ <34>.<3>
 [4] │ ab<123>
 [5] │ <5>b
 [6] │ <6> <5>
 [7] │ <7>
 [9] │ ac<4235432>
[10] │ <45>.<3>mg/dl
[11] │ abc<500>ml <3>unit <3>:<40>AM

です。