• 締切済み

ダブルクォートで囲まれた文字列の取り出し

Windows環境でRuby 1.8.7を使用しております。 ----sample1.txt----- hoge"foo\"bar\"foo"hage"bar\"baz\"bar"hoge ------------------ ファイルから1行ずつテキストを読み込んで処理を行います。上のsample.txtの様な行を読み込んだ場合にダブルクォートで囲まれた部分 foo\"bar\"foo bar\"baz\"bar を取り出すのにはどの様な正規表現を用いればよろしいでしょうか? エスケープされたダブルクォートを除ける上手い方法がわかりません。 また、ダブルクォートで囲まれた部分が複数行にまたがる場合はどの様に処理をすれば良いでしょうか? -----sample2.txt----- hoge"foo \"bar\" baz" hage ---------------------- -----sample3.txt----- hoge"foo \"ba r\"baz" hage ---------------------- 最初の例のように1行の場合は File.foreach(file) do | line | …… end で良いのですが、複数行の場合には同じように単純には行きません。 ダブルクォートの数を数えて、奇数の場合は偶数になるまで次行をくっつける様な処理を考えているのですが、もっと適切な方法はありますか? 宜しくお願いします。

  • Ruby
  • 回答数1
  • ありがとう数4

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

前者については "((?:[^\\"]|\\.)*)" にマッチさせればいいと思う. 後者は「全体を 1つの文字列にする」のが最も単純ではないでしょうか.

siffon9
質問者

お礼

ご回答ありがとうございました。 前者の正規表現はこれで上手くいっているようです。何故上手くいくのか頭を捻る必要がありますが…… 後者についてですが、全体をまとめるというのは行いたくないのです。 理由は、巨大なファイルを読むとメモリ不足で落ちることが以前あったということと、同時に他の処理を基本1行ずつで行いたいということからです。

関連するQ&A

  • 文字列検索

    文字列検索 テキストファイルの検索を行いたいです. 下記のようなサンプルファイルでfooを検索し, 含まれるならマッチした個数,含まれないならnilを返す関数を作りたいです. mecabを用いて形態素解析を1行ずつしようかと思ったんですが, 大量のファイルを処理する予定なので,オーバヘッドが気になります. 関数でgrepがあるみたいですが,マッチした行しか返されません. 標準関数で1行ずつよみこんで,1行のなかでマッチした回数を返す関数はありますか? --sample.txt-- foo foo bar bar foo hoge,hoge,hoge,hoge hage-hage-hage-foo -- end --

    • ベストアンサー
    • Ruby
  • 文字列からダブルクオートの削除

    お世話になります、 CSVからデータを取得してDBに書き込む処理を行っているのですが、CSVデータで型が文字のものはダブルクオート(")でくくっています。 (例) "りんご",100,"円" "ばなな",200,"ドル" このままデータをStringTokenizerクラスを使用して取得した場合りんごは("りんご")のようにダブルクオートがついた状態で取得されてしまいます。 ダブルクオートを取り外す方法またはメソッドを教えていただきたいのですが、よろしくお願いします。

    • ベストアンサー
    • Java
  • シングルクォート、ダブルクォート使用方法

    初心者で勉強中です。 相当素人な質問なんですがよろしくお願いします。 Perlで使われる、シングル、ダブルクォートの自分の認識なのですが ・ダブルクォートは変数やエスケープ文字を評価してくれる。 ・シングルはそのまま文字列として出力される。 ということだと思っているのですがただ、『print』の後の表示させる文字列、数字などがシングルで囲まれていたりダブルだったり、またどちらも使わない場合などあるのですがこの使い分けはどのようにすれば良いかわかりません。 単に文字列の場合でもダブルクォートで囲っていたりと・・・ 以下の例ですと use strict; print "Content-type: text/html\n\n"; my $hensu = 1; print $hensu."<br>\n"; $hensu = "moji"; print "$hensu"; 上記をブラウザ出力すると 1 moji となるということなのですが、数字であればダブルクォートで囲まなくても展開されるということでしょうか?また後ろの2行の $hensu = "moji"; print "$hensu"; とは、どちらもダブルクォートで囲む必要があるのでしょうか。 法則性についてどなたか分かるかた、おしえていだだけますでしょうか。

    • ベストアンサー
    • Perl
  • 2つのファイルを用いた文字列置換(削除)の方法

    こんにちは。 テキストファイルA.txtに、検索したい文字列を1行ずつ入れておき、別のテキストファイルB.txtのうち、A.txtにある文字が含まれている行を削除するという作業をしたいです。 例えば A.txt AAA BBB B.txt hoge hogeAAAhoge hogeBhoge hogeBBBhoge の場合、 hoge hogeBhoge を出力させたいです。 このような処理ができる方法はないでしょうか?(コマンドやプログラム等)

  • unixのawkについて

    unixでawkを使ってフルパスからディレクトリとファイル名に分けようと しているのですが、上手くいきません。 例えば ①/aaa/bbb/ccc ②/111/222/333/hoge.txt ③/hoge/foo/bar/dk@0:1 を ①/aaa/bbb と ccc ②/111/222/333 と hoge.txt ③/hoge/foo/bar と dk@0:1 としたいのです。 echo "/111/222/333/hoge.txt" | gawk '{sub(/\/.*$/,"",$0); print}' としてみたのですが、 ディレクトリだけを取り出そうとしたのですが上手くいきません。 よろしくお願いします。 OSは、Solaris、Linuxになります。

  • エクセルマクロで文字列にメタキャラを付加したい

    宜しくお願いいたします。 エクセルマクロでテキストファイルに出力させる処理を考えているのですが その際メタキャラコードを付加する場合の使い方を教えて頂けないでしょうか EX:行頭にタブを付けたい場合 Dim foo As String foo = "hoge" foo= \t + foo このように書くとエラーが出るのですが、どのように書けば良いのでしょうか?

  • 同一ファイルからの文字列検索

    お世話になります。 今、ファイル処理を勉強しています。 hoge.txtに文字列が格納されています。 (hoge.txt) --------------------- suzuki yamada kimura tanaka ito suzuki kimura --------------------- hoge.txtの上の行より、下に検索を行い、 一致した場合、printf("HIT\n");と出力します。 動きは、 suzukiを検索文字列し、yamada~kimuraまで検索を行い、 もしヒットした場合、出力表示します。 suzukiが検索終了すると、次のyamadaを検索文字列として、 kimura~kimuraを検索します。 この動作を最後の行まで行えば終了です。 下記のfgets()で1行分を取得してからの 次の行への移行がわかりません。 FILE *fp; char name[256]; if( (fp =fopen( "hoge.txt", "r )) == NULL ){ return 0; } while( fgets(name, sizeof(name), fp ) != NULL ){ //ここで次の行以下とstrstr()で比較を行う } お手数をお掛けしますが、よろしくお願い致します。

  • foo bar baz qux・・・・?

    himajin2003の頃 「hogeの意味」について聞いたことがあったが 今回はその第二弾である。 今日、あるサイトのコンテンツを見ていたら 「quxは知る人ぞ知る、foo bar bazの次である」という記述を見つけた。 基本的に僕が見たことがあるのはfoo bar までであり、今日知ってびっくりした。 さて、これって何の順番なのでしょう? 何が根拠なのでしょう?

  • ダブルクォートで囲まれたCSVファイルについて

    CSVを読みこんで配列変換するロジックを考えていますがうまくいきません。 ソースは以下の通りです。 Dim objFs Dim objSm Dim strLine Dim arySplit Set objFs = CreateObject("Scripting.FileSystemObject") Set objSm = objFs.OpenTextFile(C:\sample.csv, 1) Do Until objSm.AtEndOfStream strLine = objSm.ReadLine strLine = Right(strLine, Len(strLine) - 1) strLine = Left(strLine, Len(strLine) - 1) arySplit = Split(strLine, "\"\",\"\"") MsgBox UBound(arySplit) Loop Set objSm = Nothing Set objFs = Nothing ※読み込むCSVファイルはダブルクォートが付いています。 ※正常に配列に変換できたかを確認する為、MsgBoxで配列の要素数を表示しようとしています。 やりたい事は 1.まずは先頭と最後のダブルクォートを除外。 2.区切り文字(\",\")で配列に変換。  ※なぜカンマで配列に変換しないかというとダブルクォートで囲まれた値の中にカンマ文字がある為、このような事をしています。 3.変数に変換した配列を格納。 申し訳ありませんがご教授いただけませんでしょうか。 またどうか皆さんのお知恵を私にお貸しいただけませんでしょうか。 何卒、宜しくお願い致します。

  • Unix初心者による初心者シェルプログラミングです。

    Unix初心者による初心者シェルプログラミングです。 以下のようなコマンドを羅列しただけの スクリプトが300行(実質100行ぐらい)が漸くできるようになりました。 これだけで、おばかさんな私は進化してます。が・・・ 対象となる、hoge.txtは、同ディレクトリ内に別名で、200ファイル有ります。 このスクリプトがその別名、200ファイルへと対象になります。 と云う事はファイル名分の200ファイル分スクリプトを編集して用意しなくては いけなくなる。 となると・・・ 別の事をしないといけませんよね。 どうやら、同ディレクトリ内にある、全ての .txt ファイルに対してこの スクリプトを実行させるには・・・ (よくわかりませんが・・・) FILE=`/home/foo/*.txt` みたいな・・・(全然違うと思っていますが、イメージで) /home/foo/ 内の .txt ファイルを一ファイルずつ読み込んで、実行させる方法が あると思うのですが・・・ 全てを教えて貰うつもりはありません。 学習していきます。 でも、疲れてきました。 がしかし、やらなくちゃいけません。 ヒント下さい。 お願いします! > cat hogehoge.sh #!/usr/bin/sh DAY=`/usr/xpg4/bin/date '+%Y/%m/%d%a'` HUMAN=`/usr/ucb/whoami` TIME=`/usr/xpg4/bin/date '+%H:%M:%S'` echo echo "$DAY : $HUMAN : PID $$" echo echo "$0" echo echo "$TIME Let's start!" echo echo "ls -l /home/foo/hoge.txt" ls -l /home/foo/hoge.txt echo echo "cat -n /home/foo/hoge.txt | head -15" cat -n /home/foo/hoge.txt | head -15 echo echo "sed -f /home/foo/script.sed /home/foo/hoge.txt > /home/foo/new-hoge.txt" sed -f /home/foo/script.sed /home/foo/hoge.txt > /home/foo/new-hoge.txt echo echo "ls -l /home/foo/new-hoge.txt" ls -l /home/foo/new-hoge.txt echo echo "cat -n /home/foo/new-hoge.txt | head -18" cat -n /home/foo/new-hoge.txt | head -18 echo echo "sed -e '1d' -e '14d' /home/foo/new-hoge.txt > /home/foo/renewal-hoge.txt" sed -e '1d' -e '14d' /home/foo/new-hoge.txt > /home/foo/renewal-hoge.txt echo echo "ls -l /home/foo/renewal-hoge.txt" ls -l /home/foo/renewal-hoge.txt echo echo "diff /home/foo/new-hoge.txt /home/foo/renewal-hoge.txt" diff /home/foo/new-hoge.txt /home/foo/renewal-hoge.txt echo echo "sed -e '13d' -e 's/^iranai/hitsuyou/' /home/foo/renewal-hoge.txt > /home/foo/new-hoge.txt" sed -e '13d' -e 's/^iranai/hitsuyou/' /home/foo/renewal-hoge.txt > /home/foo/new-hoge.txt echo echo "ls -l /home/foo/new-hoge.txt" ls -l /home/foo/new-hoge.txt echo ・ ・ ・ ・ ・ ・ ・ ・ 300

専門家に質問してみよう