2014-07-15 3 views
1

을 피하십시오 :정규식이 코드가 불필요한 그룹

string = """a = 10 + 15 
b = 50 + b 
c = a + b 
d = c + 50""" 


letter = "([a-z])" 
signs = "(\+|\-|\*|\/)" 
regex = re.compile(r"{0} = (\d+) {1} (\d+)|" 
        r"{0} = (\d+) {1} {0}|" 
        r"{0} = {0} {1} {0}|" 
        r"{0} = {0} {1} (\d+)".format(letter, signs))signs))(\d+)".format(letter,signs)) 

나는 (정규 표현식, 문자열) .groups() 나는

('a', '10', '+', '15', None, None, None, None, None, None, None, None, None, None, None, None) 
(None, None, None, None, 'b', '50', '+', 'b', None, None, None, None, None, None, None, None) 
(None, None, None, None, None, None, None, None, 'c', 'a', '+', 'b', None, None, None, None) 
(None, None, None, None, None, None, None, None, None, None, None, None, 'd', 'c', '+', '50') 

로 끝날하지만 난 그냥 4 원하는 re.search을 할 경우 여러 떼. [VAR, val1과, 연산자을 val2]

내가 지능형리스트

[r for r in re.search(regex,string).groups() if r != None] 

을 사용하고 그러나 정규식 자체에서이 작업을 수행 할 수있는 방법이 있는지 궁금.

+0

당신이해야 할 일은 전체 정규식을'(? : ...)로 둘러 싸서 모든 그룹 대신에 네 개의 그룹 중 하나를 포착하는 것입니다. – RevanProdigalKnight

+0

나는 이것을 아직도 시도해 12 그룹을 나에게 준다. –

+0

아니요, 'r'(? : {0} = (\ d +) {1} (\ d +) | {0} = (\ d +) {}과 같이 여러 문자열을 사용하는 대신 정규식을 모두 한 문자열로 만들어야합니다. {0} {0} = {0} = {0} {1} {0} | {0} = {0} {1} (\ d +)) ' – RevanProdigalKnight

답변

2

그것은 정규식을 단순화하는 것이 가장 좋습니다 : 그러나

signs = "(?:\+|\-|\*|\/)" 

, 당신은 단지 하지 처음에 signsletter 그룹을 만들어 그들을 충분히 제거 할 수 이 경우 약간 오버로드 된 명령문을 수정해야합니다. letter :

letter = "[a-z]" 
signs = "(\+|\-|\*|\/)" 
regex = re.compile(r"({0}) = (\d+|{0}) {1} (\d+|{0})".format(letter, signs))signs))(\d+)".format(letter,signs)) 
+0

유일한 단점은 형식을 변경하려고 시도하기 때문에 \ d {1,2}을 정규식으로 사용할 수 없다는 것입니다. –

0

그룹화가 필요한 항목에는 (?:...)을 캡처 할 수없는 그룹으로 사용할 수 있지만 캡처는 할 수 없습니다. 예 : 별도의 사에서

letter = "[a-z]" 
signs = "[+*/-]" 
+0

@CasimiretHippolyte : 에프, 고마워. – Joey

+0

그러나 그것을 포착해야합니다. –