0

Python 2.xで正規表現を使用して、略語のサブセットをキャプチャする作業を行っています。そのような略語のいくつかは、次のテキストに表示されます。

# text                                    # desired capture
The certolizumab pegol (Cmzia, CZP)...      'CZP'
The drug 6-mercatopureine (6-mp) ...        '6-mp'
The merits of 5-Asasdfdsf (5-ASA) ...       '5-ASA'    

CZP最初の例では、結果を取り戻し、を無視することに関心がありCmzia,ます。

これが私が持っていた以前の正規表現です。これは、とのようなケースを照合するために必要(6-mp)です(5-ASA)

\((\S*[A-Z-0-9]\S*)\)  # captures '6-mp' and '5-ASA', respectively

上記のケースを処理するために私が行った追加は次のとおりです。

\S*\s+[A-Z-0-9]+  # I only want to capture the '[A-Z-0-9]+'

次の正規表現を使用してみました(コンテキストと混同されないように、関心のある部分を太字にしようとしましたが、うまくいかなかったようです)。

# in p1, I add the pattern to the list, separated by '|'
>>> p1 = re.compile(r'\((\S*[A-Z-0-9]\S*|\S*\s+[A-Z-0-9]+)\)')
>>> p1.findall('The certolizumab pegol (Cmzia, CZP)')
['Cmzia, CZP']

# in p2, I use a broad non-capturing group, enclosing the desired captured expressions in parentheses
>>> p2 = re.compile(r'\((?:(\S*[A-Z-0-9]\S*)|\S*\s+([A-Z-0-9]+))\)')
>>> p2.findall('The certolizumab pegol (Cmzia, CZP)')                           
[('', '', 'CZP')] 

# this is an addition to the original post
# demonstrates that the non-capturing expression doesn't prevent capture of the section \S*\s+
>>> p3 = re.compile(r'\((\S*[A-Z-0-9]\S*|(?:\S*\s+)[A-Z-0-9]+)\)')
>>> p3.findall('The certolizumab pegol (Cmzia, CZP)')                           
['Cmzia, CZP']

理想的には、出力が必要ですCZP。に対応するものを除外したいので、p1はあまりにも多くを返します。p2に関しては、目的の出力に一致するように出力を簡単に操作できることはわかっていますが、それを処理するように正規表現を変更する方法があるかどうかを知りたいと思います。\S*\s+Cmzia,

ありがとう、そしてあなたが追加の詳細/説明が必要な場合は私に知らせてください。

編集:

私はまだ正規表現が正規表現の最初の/元の部分から6-mpとをキャプチャすることを望んでいます。5-ASA

編集2:

これは上に含まれていますが、1つの場所に置いて、私の質問を要約します。

pattern = r'???'
p = re.compile(pattern)
p.findall('Stuff stuff (Cmzia, CZP) stuff stuff (5-ASA) (6-mp) stuff...')
['CZP','5-ASA','6-mp']
4

3 に答える 3

1

これは、あなたの目標を達成するために私が見つけた最も単純な正規表現です:

>>> p = "\((?:\S*,\s+)?(\S*)\)"
>>> s = "The cert pegol (Cmzia, CZP) some words (6-mp) and (5-ASA)"
>>> re.findall(p,s)
['CZP', '6-mp', '5-ASA']

アップデート

次のものはより制限的ですが、同じ結果が得られます。

>>> p = "\((?:\S*,\s+)?(\S*[A-Z-0-9]\S*)\)"
于 2012-10-24T12:17:21.197 に答える
0

何が欲しいのかよくわかりませんが、「CZP」に対応する部分の周りに一致する括弧をもう1つ追加し、外側のグループを一致させずに、次のようにしました。

>>> p3 = re.compile(r'\((?:\S*[A-Z-0-9]\S*|[A-Z-0-9]* [A-Z-0-9]*|(?:\S*\s+)([A-Z-0-9]+))\)')
>>> p3.findall('The certolizumab pegol (Cmzia, CZP)')
['CZP']
于 2012-10-24T03:04:07.213 に答える
0

私の読みが正しければ、括弧内に 1 つまたは 2 つのコンマ区切りの値が含まれている可能性があります。2 枚の場合は、2 枚目のみをキャプチャします。これを試して:

p = re.compile(r'\((?:[^,)]+,\s*)?([A-Za-z0-9-]+)\)')

開始括弧の後、(?:[^,)]+,\s*)?最初の値との一致を試みます。これは、末尾のコンマの存在によって識別されます。コンマが含まれていない限り、最初の値がどのように見えるかはあまり気にしません。[^,]+ただし、値が 1 つしかない場合に一致しすぎるという理由だけで使用することはできません。除外文字のリストに括弧を追加すると、一致が 1 セットの括弧内に含まれたままになります。

于 2012-10-26T08:34:26.953 に答える