はじめに

Error

私の紹介している正規表現に重大な不備が見つかっています。
これを修正するまで、この正規表現をそのまま使用することは推奨しません。

複雑なMarkdown太字の規則について より、
あいう**「かきく」**さしすなどの、強調する範囲の開始/終了地点が句読点・記号(Punctuation) であり、かつ普通の文字に隣接している場合、Markdownパーサーは意図したパースをしてくれない場合が多い。

そのため、そのように正しくない強調をしている箇所を、後から修正するための正規表現を模索したんだけど…

結構難儀である。

問題の正規表現

これから見苦しい正規表現を紹介するけど、これらは簡易的であり、意図しない事故を引き起こす場合がある。
例えば、

  • 置換するのは「」()に隣接しているものだけ (ちょっと面倒だった)
  • インラインコード、コードブロック内でも置換してしまう
  • 重大な不備 : アスタリスクの外側に隣接している括弧にもマッチする。これに対処するには強調範囲の内側であるか外側であるかを判断しなければならない

共通部分

  • フラグはgm
  • Punctuationとする文字クラスは
    [\s\p{P}]
    しかし一部の環境、特に私の環境だと\p{P}が思うように動作しなかったので、
    ゴリ押しの文字クラスを使用
    [\s!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~、。!?()「」『』【】]

置換する

以下の正規表現とその置換を上から順番に行うことで、一応望む通りに強調文字が修正される…?

labelregex to findreplace
spacing
emphasis strong
before brackets
(?<![\s\p{P}])\*{3}「 ***「
spacing
emphasis strong
after brackets
」\*{3}(?![\s\p{P}])」***
spacing
emphasis strong
before parentheses
(?<![\s\p{P}])\*{3}( ***(
spacing
emphasis strong
after parentheses
)\*{3}(?![\s\p{P}]))***
spacing strong
before brackets
(?<!\*パイプ[\s\p{P}])\*{2}(?!\*)「1 **「
spacing strong
after brackets
」(?<!\*)\*{2}(?!\*パイプ[\s\p{P}])1」**
spacing strong
before parentheses
(?<!\*パイプ[\s\p{P}])\*{2}(?!\*)(1 **(
spacing strong
after parentheses
)(?<!\*)\*{2}(?!\*パイプ[\s\p{P}])1)**
spacing emphasis
before brackets
(?<!\*パイプ[\s\p{P}])\*(?!\*)「1 *「
spacing emphasis
after brackets
」(?<!\*)\*(?!\*パイプ[\s\p{P}])1」*
spacing emphasis
before parentheses
(?<!\*パイプ[\s\p{P}])\*(?!\*)(1 *(
spacing emphasis
after parentheses
)(?<!\*)\*(?!\*パイプ[\s\p{P}])1)*

Todo

さらによい共通化された正規表現があるかもしれない
「」を肯定(先/後)読みの条件として、置換文字列にそれらを含まないようにするのはどうだろうか

Footnotes

  1. ※これと以下のregexに含まれるパイプをパイプと表現しています。これのせいでmarkdownがうまくパースできないためです!正しくは以下のようになります!

    (?<!\*|[\s\p{P}])\*{2}(?!\*)
    もしくは
        
    2 3 4 5 6 7 8