Если ваш выход из print_r($var)
, например:
Array ( [demo] => Array ( [0] => 10499478683521864 [1] => 07/22/1983 [2] => email@saya.com ) )
, выполните $var['demo'][0]
Если выход из print_r($var)
, например:
Array ( [0] => 10499478683521864 [1] => 07/22/1983 [2] => email@saya.com )
, то do $var[0]
def find_first_match(string, *regexes):
for regex, handler in regexes:
m = re.search(regex, string):
if m:
handler(m)
return
else:
raise ValueError
find_first_match(
foo,
(r'foo(.+)', handle_foo),
(r'bar(.+)', handle_bar),
(r'baz(.+)', handle_baz))
Для ускорения его можно было превратить весь regexes в один внутренне и создать диспетчера на лету. Идеально, это было бы превращено в класс тогда.
Я предложил бы это, поскольку это использует наименьшее количество regex для выполнения цели. Это - все еще функциональный код, но не хуже тогда Ваш старый Perl.
import re
var = "barbazfoo"
m = re.search(r'(foo|bar|baz)(.+)', var)
if m.group(1) == 'foo':
print m.group(1)
# do something with m.group(1)
elif m.group(1) == "bar":
print m.group(1)
# do something with m.group(1)
elif m.group(1) == "baz":
print m.group(2)
# do something with m.group(2)
Да, это является довольно раздражающим. Возможно, это будет работать на Ваш случай.
import re
class ReCheck(object):
def __init__(self):
self.result = None
def check(self, pattern, text):
self.result = re.search(pattern, text)
return self.result
var = 'bar stuff'
m = ReCheck()
if m.check(r'foo(.+)',var):
print m.result.group(1)
elif m.check(r'bar(.+)',var):
print m.result.group(1)
elif m.check(r'baz(.+)',var):
print m.result.group(1)
РЕДАКТИРОВАНИЕ: Brian правильно указал, что моя первая попытка не работала. К сожалению, эта попытка более длительна.
r"""
This is an extension of the re module. It stores the last successful
match object and lets you access it's methods and attributes via
this module.
This module exports the following additional functions:
expand Return the string obtained by doing backslash substitution on a
template string.
group Returns one or more subgroups of the match.
groups Return a tuple containing all the subgroups of the match.
start Return the indices of the start of the substring matched by
group.
end Return the indices of the end of the substring matched by group.
span Returns a 2-tuple of (start(), end()) of the substring matched
by group.
This module defines the following additional public attributes:
pos The value of pos which was passed to the search() or match()
method.
endpos The value of endpos which was passed to the search() or
match() method.
lastindex The integer index of the last matched capturing group.
lastgroup The name of the last matched capturing group.
re The regular expression object which as passed to search() or
match().
string The string passed to match() or search().
"""
import re as re_
from re import *
from functools import wraps
__all__ = re_.__all__ + [ "expand", "group", "groups", "start", "end", "span",
"last_match", "pos", "endpos", "lastindex", "lastgroup", "re", "string" ]
last_match = pos = endpos = lastindex = lastgroup = re = string = None
def _set_match(match=None):
global last_match, pos, endpos, lastindex, lastgroup, re, string
if match is not None:
last_match = match
pos = match.pos
endpos = match.endpos
lastindex = match.lastindex
lastgroup = match.lastgroup
re = match.re
string = match.string
return match
@wraps(re_.match)
def match(pattern, string, flags=0):
return _set_match(re_.match(pattern, string, flags))
@wraps(re_.search)
def search(pattern, string, flags=0):
return _set_match(re_.search(pattern, string, flags))
@wraps(re_.findall)
def findall(pattern, string, flags=0):
matches = re_.findall(pattern, string, flags)
if matches:
_set_match(matches[-1])
return matches
@wraps(re_.finditer)
def finditer(pattern, string, flags=0):
for match in re_.finditer(pattern, string, flags):
yield _set_match(match)
def expand(template):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.expand(template)
def group(*indices):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.group(*indices)
def groups(default=None):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.groups(default)
def groupdict(default=None):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.groupdict(default)
def start(group=0):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.start(group)
def end(group=0):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.end(group)
def span(group=0):
if last_match is None:
raise TypeError, "No successful match yet."
return last_match.span(group)
del wraps # Not needed past module compilation
, Например:
if gre.match("foo(.+)", var):
# do something with gre.group(1)
elif gre.match("bar(.+)", var):
# do something with gre.group(1)
elif gre.match("baz(.+)", var):
# do something with gre.group(1)
Используя именованные группы и таблицу отправки:
r = re.compile(r'(?P<cmd>foo|bar|baz)(?P<data>.+)')
def do_foo(data):
...
def do_bar(data):
...
def do_baz(data):
...
dispatch = {
'foo': do_foo,
'bar': do_bar,
'baz': do_baz,
}
m = r.match(var)
if m:
dispatch[m.group('cmd')](m.group('data'))
С определенным самоанализом можно автоматически сгенерировать regexp и таблицу отправки.
С другой стороны, что-то не использующее регулярные выражения вообще:
prefix, data = var[:3], var[3:]
if prefix == 'foo':
# do something with data
elif prefix == 'bar':
# do something with data
elif prefix == 'baz':
# do something with data
else:
# do something with var
, Подходит ли это, зависит от Вашей фактической проблемы. Не забывайте, регулярные выражения не являются швейцарским ножом, что они находятся в Perl; Python имеет различные конструкции для того, чтобы сделать обработку строк.
Благодаря этот другой вопрос SO :
import re
class DataHolder:
def __init__(self, value=None, attr_name='value'):
self._attr_name = attr_name
self.set(value)
def __call__(self, value):
return self.set(value)
def set(self, value):
setattr(self, self._attr_name, value)
return value
def get(self):
return getattr(self, self._attr_name)
string = u'test bar 123'
save_match = DataHolder(attr_name='match')
if save_match(re.search('foo (\d+)', string)):
print "Foo"
print save_match.match.group(1)
elif save_match(re.search('bar (\d+)', string)):
print "Bar"
print save_match.match.group(1)
elif save_match(re.search('baz (\d+)', string)):
print "Baz"
print save_match.match.group(1)
Вот как я решил эту проблему:
matched = False;
m = re.match("regex1");
if not matched and m:
#do something
matched = True;
m = re.match("regex2");
if not matched and m:
#do something else
matched = True;
m = re.match("regex3");
if not matched and m:
#do yet something else
matched = True;
Не так чисто, как первоначальный образец. Однако, она проста, понятна и не требует дополнительных модулей или смены оригинальных регексов.
.