-1

このフレーバーの文字列がたくさんあります。

#q1_a1
#q7

基本的に # は無視する必要がある記号です。# の後には、1 文字のアルファベットと数字が続きます。_オプションで、アルファベットと数字の組み合わせを(アンダーバー) の後に続けることができます。

これが私が思いついたものです:

>>> pat = re.compile(r"#(.*)_?(.+)?")
>>> pat.match('#q1').groups()
('q1', None)

問題は#q1_a1フォーマットの文字列です。私が作ったものをそのような文字列に適用すると:

>>> pat.findall('#q1_f1')
[('q1_f1', '')]

助言がありますか?

4

4 に答える 4

3

他の人が言っているように、正規表現が具体的であるほど、一致してはならないものと一致する可能性は低くなります。

In [13]: re.match(r'#([A-Za-z][0-9])(?:_([A-Za-z][0-9]))?', '#q1_a1').groups()
Out[13]: ('q1', 'a1')

In [14]: re.match(r'#([A-Za-z][0-9])(?:_([A-Za-z][0-9]))?', '#q1').groups()
Out[14]: ('q1', None)

ノート:

  1. 文字列全体のみを一致させる必要がある場合は、正規表現を^とで囲み$ます。
  2. あなたは「ある数字」と言いますが、あなたの例には一桁しか含まれていません。正規表現が複数の数字を受け入れる必要がある場合は、をに変更[0-9][0-9]+ます。
于 2013-01-27T07:47:33.383 に答える
2

一致が貪欲であるため、「.*」の一致にもアンダースコアが付けられます。最初のグループからアンダースコアを除外するには、より具体的な正規表現を作成することをお勧めします。

適切な正規表現は次のようになります。

#([a-z][0-9])_?([a-z][0-9])?

ただし、期待するすべてのデータで機能するかどうかを確認する必要があります。

Ps。誤検知が少ないため、正規表現をより具体的にする方が適切です。

于 2013-01-27T07:39:41.343 に答える
1

を使用する.*と、可能な限り貪欲にマッチします。試す:

>>> pat = re.compile(r"#([^_]*)_?(.+)?")
>>> pat.findall('#q1_f1')
[('q1', 'f1')]

同様に、より具体的な式を書くことをお勧めします。

#([a-z][0-9])(?:_([a-z][0-9]))?
于 2013-01-27T07:42:48.200 に答える
0

正規表現を使用しない簡単な代替手段:

s = '#q7'
print s[1:].split('_')
# ['q7']

s = '#q1_a1'
print s[1:].split('_')
# ['q1', 'a1']

これは、すべての文字列が。で始まることを前提としています#。そうでない場合は、簡単に検証を行うことができます。

s = '#q1_a1'
if s.startswith('#'):
    print s[1:].split('_')
# ['q1', 'a1]

s = 'q1_a1'
if s.startswith('#'):
    print s[1:].split('_')  # Nothing is printed
于 2013-01-27T07:45:35.307 に答える