正規表現について教えてください。


[]で囲まれている文字列の中で「3番目」の値を「選択」したいです。下の対象文字列だと「gda」にあたります

対象文字列:
aab[dds]faga[eada]gead[gda]ss[fafa]ss

戻り読み等を使えばできると思うんですが、どうもうまくいかず…

イメージ
(?<=ここがわからないです).*?(?=\])

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:2008/07/10 01:11:40
  • 終了:2008/07/10 04:01:18

ベストアンサー

id:rubikitch No.4

るびきち回答回数120ベストアンサー獲得回数222008/07/10 03:40:41

ポイント50pt

サクラエディタの正規表現エンジンはRuby 1.9同様「鬼車」です。

「invalid pattern in look-behind」というエラーメッセージで確信しました。

鬼車の戻り読みでは「.+?」等の長さが不確定なメタ文字が使えない仕様です。

よって、戻り読みでは「無理」が答えになります。

http://www.geocities.jp/kosako3/oniguruma/doc/RE.ja.txt

  (?<=式)           戻り読み
  (?<!式)           否定戻り読み

                    戻り読みの式は固定文字長でなければならない。
                    しかし、最上位の選択子だけは異なった文字長が許される。
                    例. (?<=a|bc) は許可. (?<=aaa(?:b|cd)) は不許可

                    否定戻り読みでは、捕獲式集合は許されないが、
                    非捕獲式集合は許される。
id:jun09

>戻り読みの式は固定文字長でなければならない。

なるほど、納得です…

もっと資料を読まないと駄目ですね。

ご回答ありがとうございました!

2008/07/10 03:59:47

その他の回答(3件)

id:pmakino No.1

まきのっぴ回答回数352ベストアンサー獲得回数282008/07/10 01:48:19

ポイント50pt

[^\[\]]* で [ と ] 以外の文字0文字以上

\[[^\[\]]+\] で [ と ] に囲まれた1文字以上となるので、

それを3回繰り返して最後の部分にだけ ( ) をつければ良いのではないかと。

つまり、

[^\[\]]*\[[^\[\]]+\][^\[\]]*\[[^\[\]]+\][^\[\]]*\[([^\[\]]+)\]

ですね。

例:

'aab[dds]faga[eada]gead[gda]ss[fafa]ss' =~ /[^\[\]]*\[[^\[\]]+\][^\[\]]*\[[^\[\]]+\][^\[\]]*\[([^\[\]]+)\]/;

print $1

出力結果

gda

それにしても見辛い…

id:jun09

さっそくのご回答ありがとうございます。

なるほど、こういう方法があるんですね。

ただ、今回の3という数字は適当で、10番目とか20番目とかを指定するケースがありそうなのです。

ですので、正規表現の数字部分をちょっといじることで「何番目の値を取得するか」を変えることができれば良いのですが…

(?<=^([^\[]*\[){3}).*?(?=\])

はじめはこれでいけるかと思ったんですが「invalid pattern in look-behind」と怒られてしまいました(サクラエディタ)

何が悪いんでしょうか…

2008/07/10 02:26:43
id:rubikitch No.2

るびきち回答回数120ベストアンサー獲得回数222008/07/10 02:18:18

ポイント50pt
s = "aab[dds]faga[eada]gead[gda]ss[fafa]ss"
s[ /\A(?:.+?\[.+?\]){2}.+?\[(.+?)\]/, 1 ]     # => "gda"

Rubyで。

\Aが文字列の先頭。/.+?\[.+?\]/の2回繰り返した後に /.+?\[(.+?)\]/ にマッチさせる。

「.+?」は最短マッチなので正規表現が簡潔になることが多い。

id:jun09

サクラエディタで試してみたところ、\1で取得することができました!

ありがとうございます。

回答していただいた内容で大満足なのですが、自分で試した

(?<=^([^\[]*\[){3}).*?(?=\])

のどこがまずいのかが気になります。

rubikitch様、pmakino様の正規表現は対象をグループ化して「\1」で取得する方法でしたが、戻り読み等を使って直接3番目の値「だけ」を取得(選択)することはできないでしょうか…

教えていただいた方法でやりたいことは実現できるので、ここから先は勉強です…

もしご存知でしたらご教示お願いいたします。

2008/07/10 03:29:12
id:pmakino No.3

まきのっぴ回答回数352ベストアンサー獲得回数282008/07/10 02:51:45

ポイント50pt

なるほど、では最初の例の繰り返し部分をまとめて

(?:[^\[\]]*\[[^\[\]]+\]){【スキップする数】}[^\[\]]*\[([^\[\]]+)\]

でいかがでしょうか。

3番目の文字列を選択したい場合は【スキップする数】を2にします。

例:

'aab[dds]faga[eada]gead[gda]ss[fafa]ss' =~ /(?:[^\[\]]*\[[^\[\]]+\]){2}[^\[\]]*\[([^\[\]]+)\]/;

print $1

出力結果

gda

id:jun09

サクラエディタで試してみたところ、\1で取得することができました!

ありがとうございます。

回答していただいた内容で大満足なのですが、自分で試した

(?<=^([^\[]*\[){3}).*?(?=\])

のどこがまずいのかが気になります。

rubikitch様、pmakino様の正規表現は対象をグループ化して「\1」で取得する方法でしたが、戻り読み等を使って直接3番目の値「だけ」を取得(選択)することはできないでしょうか…

教えていただいた方法でやりたいことは実現できるので、ここから先は勉強です…

もしご存知でしたらご教示お願いいたします。

2008/07/10 03:29:40
id:rubikitch No.4

るびきち回答回数120ベストアンサー獲得回数222008/07/10 03:40:41ここでベストアンサー

ポイント50pt

サクラエディタの正規表現エンジンはRuby 1.9同様「鬼車」です。

「invalid pattern in look-behind」というエラーメッセージで確信しました。

鬼車の戻り読みでは「.+?」等の長さが不確定なメタ文字が使えない仕様です。

よって、戻り読みでは「無理」が答えになります。

http://www.geocities.jp/kosako3/oniguruma/doc/RE.ja.txt

  (?<=式)           戻り読み
  (?<!式)           否定戻り読み

                    戻り読みの式は固定文字長でなければならない。
                    しかし、最上位の選択子だけは異なった文字長が許される。
                    例. (?<=a|bc) は許可. (?<=aaa(?:b|cd)) は不許可

                    否定戻り読みでは、捕獲式集合は許されないが、
                    非捕獲式集合は許される。
id:jun09

>戻り読みの式は固定文字長でなければならない。

なるほど、納得です…

もっと資料を読まないと駄目ですね。

ご回答ありがとうございました!

2008/07/10 03:59:47

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません