- - PR -
特定の部分だけを対象にした正規表現
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-07-22 01:14
例えば、丁目以降を全角のマイナスで連結している次のような住所データがあるとします。
「北海道札幌市北東10区20条1−22−3ほげ荘2」 で、正規表現で「丁目部分より前に出てくる算用数字」のみにマッチさせ 特定語句に置き換えることはできますでしょうか? 解決方法はいくつかあります。 1:^(.+?)(\\d+−.+)$ で2つに分離して一時変数に格納し、前半部を置き換えてから連結する。 2:(?>\\d+)(?!−)(?<!−[^−]*) .NET特有の可変長の戻り読みを使う 3:^[^\\d−]+(?:(?>(\\d+))(?!−)[^\\d−]*)* Jeffery E.F.Friedl氏のループ展開を参考にこのようにすると、 目的の数字がMatch.Group[1].Capturesに格納されるのを利用する。
1では芸がありませんし、 2ではできていますが、長い文字列に応用するとパフォーマンスが気になります。 3で、Groupsに格納されれば$nを使って置き換えに利用できるのですが、 Capturesに格納されるためそれができません。 また、2・3では現時点では.NET固有の機能のため汎用性に欠けます。 1の前半部(.+?)にマッチしたものに対して\\d+をマッチさせ\\d+−に達したらそれ以上はマッチングを中止する 正規表現が書ければいいのですが、可能でしょうか? よろしくお願い致します。 [ メッセージ編集済み 編集者: hei 編集日時 2007-07-22 01:36 ] | ||||
|
投稿日時: 2007-07-22 09:26
私でしたら芸はなくても わかりやすくて確実に動作する、動作を理解できる方法を選びます。 特に正規表現を一目で理解するのは私には無理なので、 多少重くなってもわかりやすかったり見易かったりするものを選びます。 簡単に分割できるならそれが一番早くて確実です。 >2ではできていますが、長い文字列に応用するとパフォーマンスが気になります。 先読み・後読みアサーションはそれほど重くありません。 アサーションでない場合と同程度です。 >3で、Groupsに格納されれば$nを使って置き換えに利用できるのですが、 >Capturesに格納されるためそれができません。 >また、2・3では現時点では.NET固有の機能のため汎用性に欠けます。 そもそも3が一番遅くてわかりづらいので私でしたら最初に却下です。 正規表現で汎用性を気にするならなおさら複雑な正規表現は使いません。 言語によって微妙な違いがたくさんありますから。 >1の前半部(.+?)にマッチしたものに対して\\d+をマッチさせ >\\d+−に達したらそれ以上はマッチングを中止する >正規表現が書ければいいのですが、可能でしょうか? そういった複雑な正規表現は私には書けません。 それしか思いつかない場合、 その文章どおりに、 細切れの正規表現を並べて実現します。 この件の場合は、私だったらシンプルにこれで置換します。 (?<!−.*)\d+(?!−) 汎用性を気にするなら2つに分けます。 [ メッセージ編集済み 編集者: れい 編集日時 2007-07-22 09:38 ] | ||||
|
投稿日時: 2007-07-23 23:39
1つの正規表現では不可能なようですね。
(このケースでは可変長の戻り読みでできますが) 現在DataGridViewに検索機能をつけようと思っており できるだけ1つの正規表現にまとめたかったことと、 2つに分けた場合は簡単な表現で済むので パフォーマンスを落とさずに一つの表現でまとめることも難しくはないのではと思い質問しました。 個人的には必要性は高いと感じるので、 今後このような機能が追加されるといいですね。 れいさん、ありがとうございました。 [ メッセージ編集済み 編集者: hei 編集日時 2007-07-23 23:41 ] |
1