How do you know *which* of the three has matched then?
Diez
Since the OP is processing alternative regexp's, he may be drifting
close to parsing territory. Here is a pyparsing example showing how
to match one of 'n' alternatives, and then apply functional logic
depending on which expression was matched. This example actually
shows 4 ways to address this question (in roughly increasing order of
OO-ness):
- explicit if/elif/... test on the name of the specific match to see
which alternative matched
- more Pythonic dispatch using a dict of names and corresponding
expression processing functions
- parse-time processing using pyparsing parse actions
- parse actions invoke class constructors, to return expression-
specific objects
-- Paul
from pyparsing import oneOf, Combine, Optional, Word, \
alphas, nums, alphanums, QuotedString
# define basic expressions
sign = oneOf("+ -")
integer = Combine(Optional(sign) + Word(nums))
real = Combine(Optional(sign) + Word(nums) + "." +
Optional(Word(nums)))
name = Word(alphas,alphanums) | QuotedString("'")
# define alternates with results names
item = real("real") | integer("integer") | name("name")
print "\nUse results names to determine which pattern matched"
for it in item.searchString("abc 123 -3.14 'phase of the moon'"):
if it.getName() == "real":
print "Real:", (float(it[0]))
elif it.getName() == "integer":
print "Int:", (int(it[0]))
else:
print "String:", it[0]
print "\nUse dict to dispatch to type-specific functions " \
"- more Pythonically canonical"
def processRealItem(it):
print "Real:", (float(it[0]))
def processIntegerItem(it):
print "Int:", (int(it[0]))
def processNameItem(it):
print "String:", it[0]
for it in item.searchString("abc 123 -3.14 'phase of the moon'"):
{"real" : processRealItem,
"integer" : processIntegerItem,
"name" : processNameItem }[it.getName()](it)
print "\nMove expression-specific logic into parse-time parse actions"
def convertInt(t):
return int(t[0])
def convertReal(t):
return float(t[0])
integer.setParseAction(convertInt)
real.setParseAction(convertReal)
item = real("real") | integer("integer") | name("name")
for it in item.searchString("abc 123 -3.14 'phase of the moon'"):
print "%s: %s %s" % (it.getName(), it[0], type(it[0]))
print "\nUse class constructors as parse-time parse actions " \
"- results names no longer needed"
class IntObject(object):
def __init__(self,t):
self.type, self.value = "Int", int(t[0])
class RealObject(object):
def __init__(self,t):
self.type, self.value = "Real", float(t[0])
class StringObject(object):
def __init__(self,t):
self.type, self.value = "String", t[0]
integer.setParseAction(IntObject)
real.setParseAction(RealObject)
name.setParseAction(StringObject)
item = real | integer | name
for it in item.searchString("abc 123 -3.14 'phase of the moon'"):
print "%s: %s (%s)" % (it[0].type, it[0].value,
it[0].__class__.__name__)
Prints:
Use results names to determine which pattern matched
String: abc
Int: 123
Real: -3.14
String: phase of the moon
Use dict to dispatch to type-specific functions - more Pythonically
canonical
String: abc
Int: 123
Real: -3.14
String: phase of the moon
Move expression-specific logic into parse-time parse actions
name: abc <type 'str'>
integer: 123 <type 'int'>
real: -3.14 <type 'float'>
name: phase of the moon <type 'str'>
Use class constructors as parse-time parse actions - results names no
longer needed
String: abc (StringObject)
Int: 123 (IntObject)
Real: -3.14 (RealObject)
String: phase of the moon (StringObject)