PythonのPCREに基づいていくつかの文字列を解析する必要がありますが、その方法がわかりません。
解析したい文字列は次のようになります。
match mysql m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s p/MySQL/ i/$1/
この例では、次のさまざまなアイテムを取得する必要があります。
"m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s" ; "p/MySQL/" ; "i/$1/"
PythonでのPCRE操作に関連して私が見つけた唯一のものはこのモジュールです: http://pydoc.org/2.2.3/pcre.html (しかし書かれているのは.soファイルです...)
この種の文字列を解析するためのPythonモジュールが存在するかどうか知っていますか?
Pythonがパターンや文字列の非ASCIIを処理する方法、または処理に失敗する方法には、非常に微妙な問題がいくつかあります。さらに悪いことに、これらの不一致は、=のバージョンだけでなく、大幅に異なります。 Python使用しているだけでなく、「ワイドビルド」があるかどうか。
一般に、Unicodeを使用している場合、ワイドビルドのPython 3が最適に機能し、ナロービルドのPython 2が最悪に機能しますが、すべての組み合わせPerl正規表現がどのように機能するかvis-à-visUnicodeとはまだかなりかけ離れています。 Pythonでᴘᴄʀᴇパターンを探している場合は、古いre
モジュールよりも少し遠くを探す必要があるかもしれません。
厄介な「ワイドビルド」の問題は、最終的に修正されました-あなたが使用する場合Pythonの十分に高度なリリース。 v3.3リリースノート からの抜粋です。
機能性
PEP 39 によって導入された変更は次のとおりです。
- Pythonは、BMP以外のコードポイント(つまり、U +0000からU + 10FFFF)を含むすべてのUnicodeコードポイントを常にサポートするようになりました。ナロービルドとワイドビルドの区別はなくなり、Pythonは、Windowsでもワイドビルドのように動作するようになりました。
- ナロービルドの廃止に伴い、ナロービルドに固有の問題も修正されました。例:
len()
は、非BMP文字に対して常に1を返すようになったため、len('\U0010FFFF') == 1
;- サロゲートペアは文字列リテラルで再結合されないため、
'\uDBFF\uDFFF' != '\U0010FFFF'
;- 非BMP文字のインデックス作成またはスライスは期待値を返すため、
'\U0010FFFF'[0]
は'\U0010FFFF'
ではなく'\uDBFF'
を返すようになりました。- 標準ライブラリの他のすべての関数は、非BMPコードポイントを正しく処理するようになりました。
sys.maxunicode
の値は常に1114111(16進数で0x10FFFF)になりました。PyUnicode_GetMax()
関数は、下位互換性のために0xFFFFまたは0x10FFFFのいずれかを返します。これは、新しいUnicode APIでは使用しないでください( issue 13054 を参照)。The ./configure
フラグ--with-wide-unicode
は削除されました。
標準のPythonディストリビューションのre
ライブラリで現在利用可能なものとは対照的に、 MatthewBarnettのregex
モジュールの両方Python 2およびPython 3同様 は、ほぼすべての可能な方法ではるかに優れており、最終的にはre
に置き換わる可能性があります。あなたの質問との特定の関連性彼のregex
ライブラリははるかにᴘᴄʀᴇ(iePerl互換性がはるかに高い -))re
よりもあらゆる点で、Perl正規表現のPythonへの移植が容易になります。これはゼロからの書き換えであるため(from-のように)スクラッチ、ハンバーガーのようではありません:)、それは非ASCIIを念頭に置いて書かれましたが、re
はそうではありませんでした。
したがって、regex
ライブラリは、物事へのアプローチ方法において、 TS#18:Unicode正規表現 の(現在の)推奨事項にはるかに厳密に従います。それはUTS#18レベル1の要件を満たしているか超えていますが、すべてではないにしても、通常はICU正規表現ライブラリまたはPerl自体—または特に勇気がある場合は、新しいJava 7が正規表現に更新されます。これは レベル1の要件 にも準拠しています。 = UTS#18から。
これらのレベル1の要件を満たすだけでなく、基本的なUnicodeサポートには絶対に不可欠ですが、Pythonの現在のre
ライブラリでは満たされていません素晴らしいregex
ライブラリは、 RL2.5 名前付き文字(\N{...})
)、 RL2.2 拡張書記素クラスター(\X
)、のレベル2要件も満たしています。 TS#18のリビジョン14 からの完全なプロパティに関する新しいRL2.7。
Matthewのregex
モジュールはUnicodeの大文字と小文字を区別しない一致がUnicodeで確実に機能するように、Unicodeの大文字と小文字の区別も行いますre
は機能しません。
regex
がPerlやRubyのような完全なUnicodeケースフォールディングをサポートするようになったため、以下は正しくなくなりました。
非常に小さな違いの1つは、今のところ、Perlの大文字と小文字を区別しないパターンでは完全な文字列指向の大文字と小文字が区別され、regex
モジュールでは単純な単一文字指向の大文字と小文字が区別されることですが、これは彼が調査していることです。これは実際には非常に難しい問題であり、Perlを除けば、Rubyさえも試みるだけです。
完全な大文字と小文字を区別しない一致が選択されている場合、これは(たとえば)"ß"
が"SS"
、"ss"
、"ſſ"
、"ſs"
(など)に正しく一致することを意味します。 (これは、ギリシャ文字ではラテン文字よりも明らかに重要です。)
スライドまたはドキュメントのソースコードも参照してください 私の3回目のOSCON2011トーク タイトル“Unicode Support Shootout:The Good、the Bad、and the (ほとんど)JavaScript、PHP、Go、Ruby、Python、Java、およびPerlでのUnicodeサポートの一般的な問題については醜い "。 Perl正規表現またはおそらくICU正規表現ライブラリ(名前付きキャプチャがない!))を使用できない場合は、Matthewのregex
for Pythonはおそらくあなたのベストショットです。
NᴏᴛᴀBᴇɴᴇs.ᴠ.ᴘ。 (= s’ilvousplaît、etmêmes’il nevousplaîtpas :)次の一方的な非営利の非広告は、Python regex
ライブラリの作成者によって実際にここに置かれたnotではありません。:)
regex
機能Python regex
ライブラリには超ニート機能のcornucopeiaがあり、そのうちのいくつかは他の正規表現システムはどこにでもあります。これらは、そのᴘᴄʀᴇ-nessまたはその優れたUnicodeサポートのためにそれを使用しているかどうかに関係なくチェックする価値があります。
このモジュールの優れた機能のいくつかは次のとおりです。
ismx
- typeオプション。これにより、(?i:foo)
はfooに対してのみ大文字と小文字が区別され、全体としては折りたたまれません。または(?-i:foo)
はfoo上でのみオフになります。これがPerlの仕組みです(またはできます)。agrep
とglimpse
にもあります)\L<list>
補間による暗黙の最短から最長のソート済み名前付きリスト\m
、\M
)\R
をやや不愉快に思っていますが。(\w+\s+)+
のような繰り返しキャプチャグループを許可します。ここでは、最後の一致だけでなく、最初のグループのすべての個別の一致を取得できます。 (C#もこれを行う可能性があると思います。)@+
および@-
配列と同様に、後のスライス/部分文字列操作のためのすべてのグループの開始位置と終了位置。(?|...|...|...|)
を介したブランチリセット演算子。Perlで機能する方法で各ブランチのグループ番号をリセットします。\w
、\b
、\s
などがUnicodeで機能します。\X
をサポートします。\G
継続ポイントアサーションをサポートします。re
には32ビットのインデックスしかありません)。わかりました、それは十分な誇大宣伝です。 :)
あなたが正規表現オタクである場合に検討する価値のある最後の選択肢の1つは、 Pythonライブラリバインディング からRuss Coxの素晴らしい RE2ライブラリ です。また、単純な文字ベースの大文字小文字の区別を含め、Unicodeをネイティブにサポートし、re
とは異なり、Unicodeの一般カテゴリとUnicodeスクリプトの文字プロパティの両方を提供します。 Unicode処理の種類。
RE2は、ICU、Perl、Pythonで見られる\N{...}
名前付き文字サポートなどのいくつかのUnicode機能を見逃していますが、非常に深刻な計算上の利点があり、正規表現エンジンを選択しますWebクエリなどの正規表現を介した飢餓ベースのサービス拒否攻撃が懸念される場合はいつでも。これは、正規表現が定期的に停止し、時間と空間で超指数関数的な爆発が発生するリスクを引き起こす逆参照を禁止することでこれを管理します。
RE2のライブラリバインディングは、C/C++とPythonだけでなく、Perl、特にGoでも利用できます。Goでは、標準の正規表現ライブラリがまもなく置き換えられる予定です。
'(\w/[^/]+/\w*)'
を探しています。
そのように使用され、
import re
x = re.compile('(\w/[^/]+/\w*)')
s = 'match mysql m/^.\0\0\0\n(4\.[-.\w]+)\0...\0/s p/MySQL/ i/$1/'
y = x.findall(s)
# y = ['m/^.\x00\x00\x00\n(4\\.[-.\\w]+)\x00...\x00/s', 'p/MySQL/', 'i/$1/']
Edi Weitzの Regex Coach で遊んでいるときに見つけたので、質問へのコメントのおかげで、その存在を思い出しました。
PCRE正規表現を実行する必要があり、Pythonのreモジュールが元のPCREの起源から分岐しているため、 ArkadiuszWahligのPython PCREのバインディング )も確認することをお勧めします。そうすれば、ネイティブPCREにアクセスでき、正規表現フレーバー間で変換する必要がなくなります。