正規表現で文字列データを検索したい場合。(シングルクォーテーション)

  1. 初めまして。
    いつもMeryを愛用させていただいています。ありがとうございます。
    正規表現でうまくいかない事がありまして質問させて下さい。

    以下の内容に対して、シングルクォーテーションで囲まれた文字列を検索したいのですがうまくいきません。
    始めの文字列と後の文字列の間の「' '」や「', '」までヒットして背景色が変わります。
    大変あつかましいのですが他のエディタで同じことをしてみるとうまくいきました。
    編集モード(構文の設定)は"Text"で試しています。
    置換するとうまく置換されます。「' '」や「', '」まで置換されません。
    「'ABC'」のみ検索対象として背景色が変化するように、何か設定または検索文字列の工夫はありますでしょうか?

    ご多忙化かと思いますがお時間がありましたら、お返事宜しくお願い致します。

    【内容】
     xxx('ABC')
     xxx 'ABC' 'ABC'
     xxx('ABC', 'ABC')

    【正規表現の検索文字列】
    '([^'])*?'

     |  sangou  |  返信
  2. sangou さま

    のちほど Kuro さんからご説明をいただけると思いますが、その前に、実例があったほうが
    良いかもしれないと想い、失礼ながら割り込みで発言させていただきます。

    参考
    http://www.haijin-boys.com/9.html

    上の「考察」や「問題」までをご覧下さい。

    Mery の正規表現は、これまでの「鬼車」と今回からの「鬼雲」のいずれでも、一致文字列を検索するのは
    「 1 文字ずつ次を検索する方式」です。エディタによって「マッチした文字列から次を検索する方式」
    を採用するものもあり、それは設計の個性です。

    開始と終了が同じ文字の対応する組の判定は、「 1 文字ずつ次を検索する方式」では少々複雑になります。

    「対応する引用府の組」の一致を判定するときは、「マッチした文字列から次を検索する方式」であれば、
    前から順に対応する組を判定し、一致した文字列内は次の検索で一致しないので、簡略です。

    しかし、括弧などのように「入れ子」になりえる対応する組の判定は「 1 文字ずつ次を検索する方式」で
    なければできません。新しく拡張された正規表現の機能である「再帰」などもこの方式が都合よいのです。
    多くの場合は、正規表現の能力を活用するには Mery の正規表現の扱いが望ましいです。

    逆に今回のように同じ文字の対応する組は苦手です、しかし、不可能ではありません。

    驚くほど長くなりますが、引用符と二重引用符の組に一致する正規表現の例を次にあげます。
    エスケープされた引用符は一致しないようにしています。

    (?=(?:(?:([\"\'`])(?:(?:(?!\1)[^\\\n])|(?:\\[^\n])|(?:\1\1))*?\1)(?:(?:(?!\1)[^\\\n])|(?:\\[^\n])|(?:\1\1))*?)+\n?$)(?:\1(?:(?:(?!\1)[^\\\n])|(?:\\[^\n])|(?:\1\1))*?(?:\1))

    このまま検索文字列に貼り付けて検索してみて下さい。

     |  inuuik  |  返信
  3. Mery を開発している者です。

    sangou さん、はじめまして。書き込みありがとうございます。
    inuuik さん、お久しぶりです。サポートありがとうございます。

    まずはじめに…
    Mery を開発していますが、正規表現に詳しいわけではありませんので、正規表現の書き方などについてはお答えできない場合が多いと思います。

    (他のユーザさんからご回答を頂けることもありますのでフォーラムにご相談を書き込んでいただくのは全然オッケーですよ~)

    なので、私からの回答としましては Mery の正規表現の仕様についての説明になってしまいますが、それも inuuik さんがご説明されているとおりで、それ以上に詳しい説明なんてできそうにありません^^;

    うーん、補足することも特になさそうな…
    inuuik さんの正規表現スゲー!と驚くことぐらいしかできないですね…

     |  Kuro  |  返信
  4. inuuikさま

    す、凄いです!バッチリ出来ました!

    正規表現で検索して過去記事を確認していたのですが関連性に気付かず再出の様な質問をしてしまいました。申し訳ありません。
    それにも関わらず、すごい正規表現やマッチング後の検索方式の違いやメリット等を教えて頂きありがとうございます。
    入れ子式の対応組や再起も調べて正規表現をもっと活用したいと思います。
    (現在レガシーASPの構文ファイル作成で他にも悩んでいたのですが引用して解決できそうな気がしてきました。)

    あの正規表現の解読はまだまだ出来ませんが、分かりやすくご説明して頂いたので大変為になりました。
    重ねてありがとうございました。

    Kuroさま

    日々?のご開発お疲れ様です。
    機能も見た目も良く操作もしやすい上にフリーなんて。
    素晴らしいエディタを使わせて頂きありがとうございます。
    (Amazonで買い物する時はここ経由で買います。笑)

    今後ともお体に気を付けてご開発頑張って下さい。
    暖かくお返事して頂きありがとうございました。
    (参考記事とても勉強になりました。)

     |  sangou  |  返信
  5. Kuro さま

    いつも Mery を使わせていただき、ありがとうございます。
    新しい版の公開にますます感謝です _o_

    > 正規表現の書き方などについてはお答えできない場合が多い
    ご謙遜 (^^)

    > うーん、補足することも特になさそうな…
    内容はすべてここの記事のパクリですのに…^^; やり過ぎました(笑)

    正規表現は もいすん で書いたときにも似たものがあったかも。
    前に書いた Markdown の強調もこれの仲間、ワンパターン技で。

    sangou さま

    よろしくお願いします。とりあえず動いてよかったです。
    長いので読むのは大変ですが、見かけだけですから…

    判定の単位は行頭から行末までです。

    組合せの判定は…、
    判定開始位置の開始文字から行末までに、
    まず対応する終了文字があり、
    そこから先に、組がないか、いくつかの組があるなら、
    これは対応する組、
    として一致にしています。

    行末から組を探しているわけです。

    なので、組にならない半端な文字が行末までにあると、
    開始位置が次の文字にずれていきます。

    これにエスケープされた途中の文字の一致除外を加えてます。

    開始・終了文字の判定は、
    カッコ(捕獲式集合)と数字指定の後方参照。
    行末までの内容判定は、先読み。
    エスケープ除外は、否定先読み。

    行頭方向への戻り読みや、保持 (\K) の判定では同じことが
    できません。

    というヒント?でカッコに分解すれば解読できると思います。
    (鬼雲の RE.ja.txt ドキュメントは常備で)

    例なので、長~い正規表現をお目にかけたのですが、
    自分ではこれをマクロにして使ってます(笑)

     |  inuuik  |  返信
  6. シングル/ダブルクォーテーションの場合であれば、
    編集モードのプロパティ画面を開き、[構文]タブの「引用符に囲まれた文字列」の設定を使うのが一番簡単かと思います。
    色指定などは「強調文字列(1)~(8)」ではなく「文字列」で設定します。

    正規表現を使うなら、inuuik さんご提案のように複雑なものになるでしょう。
    自分は読み解くだけでも精一杯です…。
    とはいえ、鬼車/鬼雲で使える「名前付きグループ」などを用いて整理できそうでしたので、参考までに書いておきます。

    (?=(?:(?:(?<q>["'`])(?<str>(?!\k<q>)[^\\\n]|\\[^\n])*?\k<q>)\g<str>*?)+\n?$)(?:\k<q>\g<str>*?\k<q>)

    構造としては、
    <q> = (["'`])   # 引用符
    <str> = ((?!\k<q>)[^\\\n] | \\[^\n])   # 引用符以外の文字
    <block> = (\k<q> \g<str>*? \k<q>)   # 引用符に囲まれた文字列
    と定義したとき、
    (?= (<block> <str>*?)+ \n?$ ) <block>
    と整理することができます。
    (実際は <q> のキャプチャが必要な関係で <block> は名前付きグループにしてません)

    なお、オリジナルにある \1\1 は \k<q>{2} となりますが、上では削除しています。
    「""」など引用符を重ねるエスケープに対応するための表現だと思われますが、機能していない様子でしたので。

     |  masme  |  返信
  7. masmeさま

    アドバイスありがとうございます。
    教えて頂いた通り「引用符に囲まれた文字列」の設定で上手くいくことに気付きました。
    しかし、今回(.NETでない)ASPの構文でインライン部分(<%~%>)の間のシングルクォーテーションは行コメントとして、JavaScriptの部分は文字列の引用符として扱いたく2つのパターンの切り替え方が上手くいかず困ってます。 その事を伝えておらず大変失礼しました。
    (現在、HTMLの構文ファイルを基にVBScriptの定義情報を追加してあとは<%~(改行あり)~%>の間のシングルクォーテーションを行コメントとしてあつかえないかなと探っております。質問の仕方が間違っていましたので解決できませんでしたらまた別で質問させて頂きます。すみませんでした。)

    整理して下さった正規表現でもバッチリ、ペアの検索が出来ました。

    「名前つきグループ」の存在を教えて頂きありがとうございます!
    こういう風に短縮できるのですね!勉強になります。
    (こちらも鬼雲の RE.ja.txt ドキュメントを見ながら勉強中です。)

    今後の正規表現に役立てていきたいと思います。
    ありがとうございました!

     |  sangou  |  返信
  8. inuuikさま

    優しくご説明して下さってありがとうございます!
    まだ完全に解読OKとまではいっていませんが、
    どういう流れてマッチングさせているかはお蔭様で掴んできました。
    (只今、教えて頂いた鬼雲の RE.ja.txt ドキュメントを見ながら勉強中です。)

    もし、完全解読出来なくてもコレはコレとしてこの先ずっと使える技術です。
    ありがとうございました!

     |  sangou  |  返信