-1

Python を使ってウィキテキストを処理したいのですが!

たとえば、オリジナル:

== 123 ==
=== 1234 ===

に:

<h2> 123 </h2>
<h3> 1234 </h3>

どうやってするか!正規表現が必要ですか? それはうまくいきますか?

import re
block_head = r"""
(?P<head>
    ^
    \s*
    (?P<head_head> =+ )
    \s*
    (?P<head_text> .*? )
    \s*
    (?P=head_head)
    \s*
    $
  )
"""
while 1:
somestring=raw_input()
dict1=re.search(block_head,somestring, re.X).groupdict()
if(dict1['head_head']=='======'):
    print '<h6>'+dict1['head_text']+'</h6>'
if(dict1['head_head']=='====='):
    print '<h5>'+dict1['head_text']+'</h5>'
if(dict1['head_head']=='===='):
    print '<h4>'+dict1['head_text']+'</h4>'

そして、私はこの問題をどのように解決するのだろうか:

abc'''123'''aa

abc<b>123</b>aa
4

3 に答える 3

2

はい、おそらく正規表現を使いたいでしょう。

ただし、車輪の再発明は避けたいと思うかもしれません。MoinMoin python wiki プラットフォームは、実際に正規表現を使用して入力テキストを解析するMedia Wiki 形式ハンドラーを含む、さまざまな形式ハンドラーを既に実装しています。

その実装から借りるために、正規表現を使用します。

block_head = r"""
    (?P<head>
        ^
        \s*
        (?P<head_head> =+ )
        \s*
        (?P<head_text> .*? )
        \s*
        (?P=head_head)
        \s*
        $
    )
"""

=1 つ以上の文字の後にテキストが続き、その後に同じ数の文字が続く行に一致します=。これはフラグ付きの詳細な正規表現構文を使用しますre.X(空白は無視されます)。

その正規表現を使用すると、ヘッダーを照合し、文字数を数えることでヘッダーの「レベル」を把握できます=

>>> re.search(block_head, '=== Some header! ===', re.X).groupdict()
{'head_text': 'Some header!', 'head': '=== Some header! ===', 'head_head': '==='}

冗長でないバージョンは次のようになります。

block_head = r"(?P<head>^\s*(?P<head_head>=+)\s*(?P<head_text>.*?)\s*(?P=head_head)\s*$)"

それを出発点として使用し (各部分が何をするかを理解するまで、reモジュールのドキュメントを注意深く読んでください)、そこから拡張してください。

于 2013-03-10T14:39:02.983 に答える
0

独自の実装を試みている間は、参考としてPyPiのPythonモジュールのMarkdownを確認してください。実行してから、ビルドおよびインストールされたパッケージのsudo pip install markdownPythonインストールディレクトリ/lib/python.version/site-packages/markdownに移動します。または、上のリンクからアーカイブをダウンロードして、元のソースを参照することもできます。そこにはたくさんありますが、あなたがやろうとしていることのいくつかの良い例を見つけることができるはずです。

于 2013-03-10T14:56:10.583 に答える
0
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 文字の最後の連続=(?<!=)が始まる文字列内のこの位置の直前に、別の=が存在しない必要がある」ことを意味します。

于 2013-03-10T15:34:04.853 に答える