import re
reg = re.compile('^(={1,3})(.+?)\\1 *\r?$',re.MULTILINE)
s = '''== B123 ==
=== Z1234 ==='''
def ripl(m, d = {'=':'h1','==':'h2','===':'h3'}):
return '<{0:s}>{1:s}</{0:s}>'.format(d[m.group(1)],m.group(2))
print reg.sub(ripl,s)
正規表現のパターンの説明:
^
re.MULTILINE
フラグなしは、「文字列の開始」を意味します。
^
withre.MULTILINE
は「行または文字列の開始」を意味します。
(={1,3})
はキャプチャ グループ、グループ 1 です
。1 ~ 3 文字の=をキャッチしますが、グループの前に があるため、^
これらの=をキャッチするのは行頭のみです。
(.+?)
はキャプチャ グループ番号 2 です。
.+?
すべての種類の文字をキャッチします ( \nを除く。re.DOTALL フラグのないドットは\n
と一致しない(.+)
ため) 。可能な限り:まあ、現在の場合、ドットは\nと一致しないため、行末まで、つまり\nの前の位置まで進み、2 番目のグループが 2 番目のシリーズをキャッチします。=または==または===も、私たちが望んでいないものです。
しかし、?
後.+
はこの表現を命じます.+
貪欲でないこと、つまり、後で指定されたものにぶつかるとすぐにどこかで停止することです.+?
そのため、その前で停止する\\1 *\r?$
文字のグループを定義します。と の間.+?
の括弧は、この観点からは重要ではありません。
その意味は : )
.+?
\\1 *\r?$
- 1) 行の前にあるのと同じ文字グループ。グループ 1 でキャッチする必要があります。これは次のように表されます。
\\1
- 2) その後、おそらく一連の空白 (役に立たないが、この場所にいくつかある可能性があります)
- 3) \rの可能性がありますが、必須ではありません。これを置くのは、Windows では行末が\r\nであるからです
- 4) 最後に、
$
re.MULTILINE は for と同じようにその意味を変更するため、「行または文字列の終わり」を意味します。^
この条件を付けて、一致する一連の=または==または===が最後になること\\1 *\r?$
を断言します。なぜなら、その部分は最初に遭遇した部分で止まると言われているからです。そして、最初が最後ではない場合はどうなりますか? この場合、グループ 1 と同じグループが行末にある場合にのみ、グループ 1 と同じグループの前で停止するように指定する必要があります。したがって、これにより、charachters =が行に存在する可能性が生じます (実際、私はウィキで可能かどうかわかりませんが、この場合について考えました).+?
.+?
.
注
:以下の場合を除外する
===abcd=====
======ijk==
に変換されます
<h3>abcd==</h3>
<h2>====ijk</h2>
パターンは'^(={1,3}(?!=))(.+?)(?<!=)\\1 *\r?$'
この部分は、「文字列内で 1 ~ 3 文字の連続=(?!=)
が止まるこの位置の直後に、別の=が存在しないこと」を意味します。
この部分は、「1 ~ 3 文字の最後の連続=(?<!=)
が始まる文字列内のこの位置の直前に、別の=が存在しない必要がある」ことを意味します。