문제

이 코드는 작동합니다.

from pyparsing import *

zipRE = "\d{5}(?:[-\s]\d{4})?" 
fooRE = "^\!\s+.*"

zipcode = Regex( zipRE )
foo = Regex( fooRE )

query = ( zipcode | foo )



tests = [ "80517", "C6H5OH", "90001-3234", "! sfs" ]

for t in tests:
    try:
        results = query.parseString( t )
        print t,"->", results
    except ParseException, pe:
        print pe

두 가지 문제에 갇혀 있습니다.

1- 사용자 정의 기능을 사용하여 토큰을 구문 분석하는 방법. 예를 들어, 숫자가 우편 코드인지 확인하기 위해 Regex 대신 사용자 정의 로직을 사용하고 싶다면. 대신에:

zipcode = Regex( zipRE )

아마도:

zipcode = MyFunc()

2- 문자열이 어떤 구멍을 뚫는 지 결정하려면 어떻게해야합니까? "80001"구문 분석 "zipcode"에 대한 구문 분석이지만 pyparsing을 사용하여 어떻게 결정합니까? 나는 그 내용에 대한 문자열을 구문 분석하는 것이 아니라 단순히 어떤 종류의 쿼리인지 결정합니다.

도움이 되었습니까?

해결책

두 번째 질문은 쉽기 때문에 먼저 대답하겠습니다. 쿼리 변경 결과 이름 이름을 다른 표현식에 할당합니다.

query = ( zipcode("zip") | foo("foo") ) 

이제 반환 된 결과에서 getName ()을 호출 할 수 있습니다.

print t,"->", results, results.getName()

기부:

80517 -> ['80517'] zip
Expected Re:('\\d{5}(?:[-\\s]\\d{4})?') (at char 0), (line:1, col:1)
90001-3234 -> ['90001-3234'] zip
! sfs -> ['! sfs'] foo

결과의 fooness 또는 zipness를 사용하여 다른 기능을 호출하려면, PORSE 작업을 FOO 및 ZipCode 표현식에 첨부하여 구문 분석 시간 에이 작업을 수행 할 수 있습니다.

# enclose zipcodes in '*'s, foos in '#'s
zipcode.setParseAction(lambda t: '*' + t[0] + '*')
foo.setParseAction(lambda t: '#' + t[0] + '#')

query = ( zipcode("zip") | foo("foo") ) 

이제 제공 :

80517 -> ['*80517*'] zip
Expected Re:('\\d{5}(?:[-\\s]\\d{4})?') (at char 0), (line:1, col:1)
90001-3234 -> ['*90001-3234*'] zip
! sfs -> ['#! sfs#'] foo

첫 번째 질문을 위해, 나는 당신이 어떤 종류의 기능을 의미하는지 정확히 모릅니다. Pyparsing은 단지 Regex (예 : Word, Keyword, Literal, Caselessliteral)보다 더 많은 구문 분석 클래스를 제공하며, '+', '|', '^', '~', '@'및 '@'및 '+', '|', '~', '@'및 '파서를 구성합니다. '*'운영자. 예를 들어, 미국 사회 보장 번호를 구문 분석하고 싶지만 Regex를 사용하지 않으려면 다음을 사용할 수 있습니다.

ssn = Combine(Word(nums,exact=3) + '-' + 
        Word(nums,exact=2) + '-' + Word(nums,exact=4))

인접한 "단어"에 대한 단어 일치 생성자의 주어진 문자로 구성된 단어는 일치하는 토큰을 단일 토큰으로 결합합니다.

그러한 숫자의 잠재적 목록을 구문 분석하고 싶다면 '/'s로 구분 된 다음을 사용하십시오.

delimitedList(ssn, '/')

또는 1에서 3 사이의 숫자가있는 경우 구분자가없는 경우 사용하십시오.

ssn * (1,3)

그리고 모든 표현식에는 결과 이름이나 구문 분석 작업이 첨부되어 구문 분석 중에 구문 분석 된 결과 또는 기능을 더욱 풍부하게 할 수 있습니다. 앞으로 클래스를 사용하여 중첩 된 괄호리스트, 산술 표현식 등과 같은 재귀 구문자를 구축 할 수도 있습니다.

내가 pyparsing을 썼을 때의 의도는 기본 빌딩 블록에서 파서 의이 구성이 파서를 만드는 주요 형태가 될 것입니다. 나중에 릴리스에서 regex를 최고의 이스케이프 밸브로 추가 한 것은 나중에 릴리스되었습니다. 사람들이 구식을 구축 할 수 없다면, 그들은 Regex의 형식으로 돌아갈 수 있었으며, 이는 시간이 지남에 따라 분명히 힘을 입증했습니다.

또는 다른 포스터에서 알 수 있듯이 Pyparsing 소스를 열고 기존 클래스 중 하나를 서브 클래스하거나 구조에 따라 직접 쓸 수 있습니다. 다음은 쌍을 이루는 문자와 일치하는 수업입니다.

class PairOf(Token):
    """Token for matching words composed of a pair
       of characters in a given set.
    """
    def __init__( self, chars ):
        super(PairOf,self).__init__()
        self.pair_chars = set(chars)

    def parseImpl( self, instring, loc, doActions=True ):
        if (loc < len(instring)-1 and 
           instring[loc] in self.pair_chars and
           instring[loc+1] == instring[loc]):
            return loc+2, instring[loc:loc+2]
        else:
            raise ParseException(instring, loc, "Not at a pair of characters")

하도록 하다:

punc = r"~!@#$%^&*_-+=|\?/"
parser = OneOrMore(Word(alphas) | PairOf(punc))
print parser.parseString("Does ** this match @@@@ %% the parser?")

제공 :

['Does', '**', 'this', 'match', '@@', '@@', '%%', 'the', 'parser']

(후행 싱글 ''의 누락에 주목합니까?)

다른 팁

지퍼 코드와 foo를 별도로 사용할 수 있으므로 문자열이 일치하는지 알 수 있습니다.

zipresults = zipcode.parseString( t )
fooresults = foo.parseString( t )

나는 없다 pyparsing 모듈이지만 Regex 기능이 아닌 클래스 여야합니다.

당신이 할 수있는 일은 그것으로부터 서브 클래스와 행동을 사용자 정의하는 데 필요한 방법을 무시한 다음 대신 서브 클래스를 사용하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top