はじめに
Error
私の紹介している正規表現に重大な不備が見つかっています。
これを修正するまで、この正規表現をそのまま使用することは推奨しません。
複雑なMarkdown太字の規則について より、
あいう**「かきく」**さしすなどの、強調する範囲の開始/終了地点が句読点・記号(Punctuation) であり、かつ普通の文字に隣接している場合、Markdownパーサーは意図したパースをしてくれない場合が多い。
そのため、そのように正しくない強調をしている箇所を、後から修正するための正規表現を模索したんだけど…
結構難儀である。
問題の正規表現
これから見苦しい正規表現を紹介するけど、これらは簡易的であり、意図しない事故を引き起こす場合がある。
例えば、
- 置換するのは
「」()に隣接しているものだけ (ちょっと面倒だった) - インラインコード、コードブロック内でも置換してしまう
- 重大な不備 : アスタリスクの外側に隣接している括弧にもマッチする。これに対処するには強調範囲の内側であるか外側であるかを判断しなければならない
- …
共通部分
- フラグは
gm - Punctuationとする文字クラスは
しかし一部の環境、特に私の環境だと[\s\p{P}]\p{P}が思うように動作しなかったので、
ゴリ押しの文字クラスを使用[\s!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~、。!?()「」『』【】]
置換する
以下の正規表現とその置換を上から順番に行うことで、一応望む通りに強調文字が修正される…?
| label | regex to find | replace |
|---|---|---|
| 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
さらによい共通化された正規表現があるかもしれない
「」を肯定(先/後)読みの条件として、置換文字列にそれらを含まないようにするのはどうだろうか