Nested Regex Conditionals

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Paul Dale

    #1

    Nested Regex Conditionals


    Hi All,

    I know that several of you will probably want to reply "you should write
    a parser", and I may. For that matter any tips on theory in that
    direction would be appreciated.

    However, if you would indulge me in my regex question I would also be
    most grateful.

    I'm writing an edi parser and to be in compliance with the specification
    I need to have conditionals that are dependent on conditionals. In some
    regular expression implementations this is possible. The code ...

    #!/usr/bin/env python
    import re
    pattern = re.compile(r"""
    (?P<first>(firs t))
    (?(first)
    (?P<second>(sec ond))
    )
    (?(second)
    (?P<third>(thir d))
    )
    """, re.VERBOSE)
    string = 'firstsecondthi rd'
    match = re.match(patter n,string)
    print match.group('fi rst','second',' third')

    Prints ('first', 'second', None)

    and I haven't found any way to have a second conditional, nor any
    reference to it in any documentation I've found.

    Am I missing something, and it is possible? Or is it not possible in python?

    It seems like it might be a bug, as it knows there is a group (None,
    instead of an IndexError), but it doesn't match ...

    Thanks for any help :)

    Paul
  • Paul McGuire

    #2
    Re: Nested Regex Conditionals

    This works (note relocated right paren at (?(second) ):

    #!/usr/bin/env python
    import re
    original_patter n = re.compile(r"""
    (?P<first>(firs t))
    (?(first)
    (?P<second>(sec ond))
    )
    (?(second)
    (?P<third>(thir d))
    )
    """, re.VERBOSE)
    pattern = re.compile(r"""
    (?P<first>(firs t))
    (?(first)
    (?P<second>(sec ond))
    )
    (?(second))
    (?P<third>(thir d))
    """, re.VERBOSE)

    string = 'firstsecondthi rd'
    match = re.match(patter n,string)
    print match.group('fi rst','second',' third')


    Prints out:
    ('first', 'second', 'third')


    The pyparsing alternative looks like:

    first = Literal("first" ).setResultsNam e("first")
    second = Literal("second ").setResultsNa me("second")
    third = Literal("third" ).setResultsNam e("third")

    # define line
    line = first + second + third

    print line.parseStrin g("firstsecondt hird")

    Prints out:
    ['first', 'second', 'third']

    -- Paul

    Comment

    Working...