2017-05-25 11 views
3

引用符内のすべてのスペースをRでアンダースコアに置き換えたいと思います。私の始まりの努力は失敗し、私は一重引用符も二重引用符にも達していません。複数の引用符で囲まれた文字列内でREGEXでマッチ&置換する

require(stringi) 
s = "The 'quick brown' fox 'jumps over' the lazy dog" 
stri_replace_all(s, regex="('.*) (.*')", '$1_$2') 
#> [1] "The 'quick brown' fox 'jumps_over' the lazy dog" 

助けに感謝します。

+1

;) – geotheory

+0

あなたが内部のエスケープシーケンスを考慮する必要がありますか?適切にエスケープされた文字列を扱っていますか?関連する '' .... .... ''部分文字列全体をマッチさせることができれば、マッチ内のテキストを置き換えることができます。 –

答えて

4

はあなたが'以外の1つの以上の文字があり、その後、'で終わり、その後、'で始まるすべての重複しない部分文字列と一致する必要がありますと仮定しましょう。パターンは'[^']+'です。

その後、次の基本Rコードを使用することがあります。

x = "The 'quick cunning brown' fox 'jumps up and over' the lazy dog" 
gr <- gregexpr("'[^']+'", x) 
mat <- regmatches(x, gr) 
regmatches(x, gr) <- lapply(mat, gsub, pattern="\\s", replacement="_") 
x 
## => [1] "The 'quick_cunning_brown' fox 'jumps_up_and_over' the lazy dog" 

this R demoを参照してください。すぐに無\前 -

  • (?<!\\):または、gsubfnを使用します。

    (?<!\\)(?:\\{2})*\K'[^'\\]*(?:\\.[^'\\]*)*' 
    

    詳細

    > library(gsubfn) 
    > rx <- "'[^']+'" 
    > s = "The 'quick cunning brown' fox 'jumps up and over' the lazy dog" 
    > gsubfn(rx, ~ gsub("\\s", "_", x), s) 
    [1] "The 'quick_cunning_brown' fox 'jumps_up_and_over' the lazy dog" 
    > 
    

    エスケープシーケンスをサポートするには、はるかに複雑なPCRE正規表現を使用することができます現在の場所

  • (?:\\{2})* - ゼロ以上の配列2 \ S
  • \Kから一致リセットオペレータ
  • ' - ゼロ以上 - '\
  • (?:\\.[^'\\]*)*よりゼロ以上の文字他の -
  • [^'\\]*単一引用符
    • \\. - a \のいずれかのc単一引用符 - HARが、改行
    • [^'\\]*から'\
  • '以外のゼロ個以上の文字。

そしてR demo

x = "The \\' \\\\\\' \\\\\\\\'quick \\'cunning\\' brown' fox 'jumps up \\'and\\' over' the lazy dog" 
cat(x, sep="\n") 
gr <- gregexpr("(?<!\\\\)(?:\\\\{2})*\\K'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'", x, perl=TRUE) 
mat <- regmatches(x, gr) 
regmatches(x, gr) <- lapply(mat, gsub, pattern="\\s", replacement="_") 
cat(x, sep="\n") 

出力のようになります。

あなたが安っぽい心を持っている場合にのみ
The \' \\\' \\\\'quick \'cunning\' brown' fox 'jumps up \'and\' over' the lazy dog 
The \' \\\' \\\\'quick_\'cunning\'_brown' fox 'jumps_up_\'and\'_over' the lazy dog 
+0

私は同じアイデアを持っていました(つまり、 - とにかく 'regmatches'を2度実行しなければならないので、' mat 'を別に保存する利点があるかどうかはわかりません。 +1に関係なく - 'regmatches <'は本当に非常に便利な関数です。 – thelatemail

+0

はい、PCREの正規表現オプションを使用したベースRも非常に強力で、エスケープシーケンス(アップデートを参照)を処理する必要があるときは唯一の最も便利なオプションです。 –

+0

包括的で、Wiktorに感謝します。私はPCREの例を理解しようとするつもりではない。 – geotheory

1

はこれを試してみてください:

require(stringi) 
s = "The 'quick brown' fox 'jumps over' the lazy dog" 
stri_replace_all(s, regex="('[a-z]+) ([a-z]+')", '$1_$2') 
+1

これは '' '+' letters'と 'letters' +' ''の間にスペースが1つしかないことを前提としています。 –

+0

引用符で囲まれた2つ以上の単語に対しては機能しません。 – Rahul

+0

だと思います。*あまりにも貪欲です。だからこそ、特定のことが手紙のために役立つかもしれません。あなたが持っている文字列が大文字か特殊文字かを修正する必要があります。 – AChervony

関連する問題