2014-07-24 1 views
2

"<name>(<number>)"의 문자열을 구문 분석 할 수있는 파이썬 정규 표현식을 작성하려고합니다. 여기에서 <number>은 선택 사항입니다.파이썬의 정규 표현식을 사용하여 문자열의 끝에 선택적 숫자를 추출합니다.

예를 들어 'sclkout'을 전달하면 끝에 숫자가 없으므로 단지 'sclkout'과 일치해야합니다. 입력이 'line7' 인 경우 'line''7'과 일치해야합니다. 이름에는 그 안에 숫자도 포함될 수 있으므로 'dx3f'을 입력하면 'dx3f'이되어야하지만 'dx3b0'의 경우 'dx3b'0과 일치해야합니다.

내가 먼저 시도 무엇 :

import re 

def do_match(signal): 
    match = re.match('(\w+)(\d+)?', signal) 
    assert match 
    print "Input = " + signal 
    print "group1 = " + match.group(1) 
    if match.lastindex == 2: 
     print "group2 = " + match.group(2) 
    print "" 


# should match 'sclkout' 
do_match("sclkout") 

# should match 'line' and '7' 
do_match("line7") 

# should match 'dx4f' 
do_match("dx4f") 

# should match 'dx3b' and '0' 
do_match("dx3b0") 

이 물론 때문에 (\w+) 그룹의 욕심 일치의 잘못이다, 그래서 나는 비 욕심에 그 설정을 시도 :

match = re.match('(\w+?)(\d+)?', signal) 

이를 그러나 문자열의 첫 문자에만 일치합니다.

답변

1

당신은이 같은 소유 한정 기호를 사용할 수 있습니다

^(?<name>\w+?)(?<number>\d+)?$ 

또는 ^(\w+?)(\d+)?$, 당신은 이름을 캡처 그룹을 원하지 않는 경우. http://rubular.com/r/44Ntc4mLDY

+0

이것은'(\ w +?) (\ d +)? $'와 같이 문자열 시작 부분을 신경 쓰지 않고 작동합니다. 감사! –

2

이에 대한 정규식 필요가 없습니다

from itertools import takewhile 
def do_match(s): 
    num = ''.join(takewhile(str.isdigit, reversed(s)))[::-1] 
    return s[:s.rindex(num)], num 
... 
>>> do_match('sclkout') 
('sclkout', '') 
>>> do_match('line7') 
('line', '7') 
>>> do_match('dx4f') 
('dx4f', '') 
>>> do_match('dx3b0') 
('dx3b', '0') 
+1

내가 바꿀 것's의 [:: - 1]''반전 (들) '(효율적인 명확하고 더 많은 메모리)와 함께. – Bakuriu

+0

@Bakuriu 분명히 나쁜 생각은 아닙니다. –

1

([a-zA-Z0-9]*[a-zA-Z]+)([0-9]*) 당신이 원하는 무엇인가 :

여기에 라이브 데모를 참조하십시오.

import re 
test = ["sclkout", "line7", "dx4f", "dx3b0"] 
ans = [("sclkout", ""), ("line", "7"), ("dx4f", ""), ("dx3b", "0")] 

for t, a in zip(test, ans): 
    m = re.match(r'([a-zA-Z0-9]*[a-zA-Z]+)([0-9]*)', t) 
    if m.groups() == a: 
     print "OK" 
    else: 
     print "NG" 

출력 :

OK 
OK 
OK 
OK 
관련 문제