Это супер удобно для некоторых проблем:
>>> re.search('(?P<b>.b.).*(?P<i>.i.)', 'abcdefghijk').groupdict()
{'i': 'hij', 'b': 'abc'}
Но что, если я не знаю что порядок ожидать заранее?
[обновление]
Например, скажите, что у меня есть входная переменная, содержащая некоторый неизвестный порядок символов, и это именно так происходит, что 'b' прибывает после того, как 'я'. Я хочу все еще смочь сослаться на группы для '.b'. и '.i'. не имея необходимость заказывать мой regex согласно их порядку во входном var. Так, мне жаль, что я не мог сделать что-то вроде этого, но я не знаю, возможно ли это:
>>> re.search('(?P<b>.b.)|(?P<i>.i.)', unknown_order_alphabet_str).groupdict()
{'i': 'hij', 'b': 'abc'}
[закончите обновление]
Я искал вокруг и ломал голову набор, но не могу генерировать пользу, ведет. Предположение этой функциональности не существовало бы, потому что, вероятно, единственный путь к ре, чтобы сделать это должно просканировать всю строку однажды для каждой группы (который, конечно, я мог сделать в цикле вместо этого), но я думал, что буду видеть то, что stackoverflow мозг должен был сказать об этом.
Спасибо за помощь,
Josh
Я верю, что вы хотите что-то такое:
public partial class Sample: UserControl
{
public event EventHandler TextboxValidated;
public Sample()
{
InitializeComponent();
}
private void TextBox_Validated(object sender, EventArgs e)
{
// invoke UserControl event here
if (this.TextboxValidated != null) this.TextboxValidated(sender, e);
}
}
И затем на вашей форме:
public partial class MainForm : Form
{
private Sample sampleUserControl = new Sample();
public MainForm()
{
this.InitializeComponent();
sampleUserControl.TextboxValidated += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
// do stuff
}
}
-121--1642055- >>> [m.groupdict() for m in re.finditer('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk')]
[{'i': None, 'b': 'abc'}, {'i': 'hij', 'b': None}]
Кажется, работает хорошо, хотя если у вас есть много групп, проверяющих, какая из них не Нет
может стать утомительным.
При этом будут найдены все .b.
и все .i.
соответствует в последовательности. Если вы хотите быть уверены, что он нашел один из каждого вы должны будете проверить это вручную, тоже.
Используйте вертикальную полосу («или») в образец RE и finditer
, чтобы получить все интересующие объекты соответствия: каждый из них будет иметь groupdict
с None
в качестве значения для групп, не участвующих в этом совпадении, и вы можете «объединить» символы по своему усмотрению.
Например,
import re
def mergedgroupdict(pattern, thestring):
there = re.compile(pattern)
result = {}
for mo in there.finditer(thestring):
d = mo.groupdict()
for k in d:
if k not in result and d[k] is not None:
result[k] = d[k]
return result
используется стратегия слияния, которая заключается только в выборе первого фактического соответствия для каждой именованной группы в образец. Теперь, например
>>> mergedgroupdict('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk')
{'i': 'hij', 'b': 'abc'}
>>> mergedgroupdict('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk'[::-1])
{'i': 'jih', 'b': 'cba'}
предположительно, как вы хотите, если я правильно интерпретирую ваш вопрос.
Ближе всего я могу предложить следующее:
>>> [match.groupdict() for match in re.finditer('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk')]
[{'i': None, 'b': 'abc'}, {'i': 'hij', 'b': None}]
То, как вы объедините словари, зависит от того, ожидаете ли вы более одного совпадения. Если вам нужно только одно совпадение, вы можете сделать:
>>> results = {}
>>> for match in re.finditer('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk'):
... results.update(dict((k,v) for k, v in match.groupdict().iteritems() if v is not None))
...
>>> results
{'i': 'hij', 'b': 'abc'}
Или для нескольких совпадений:
>>> results = defaultdict(lambda: [])
>>> for match in re.finditer('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijkabcdefghijk'):
... for k, v in match.groupdict().iteritems():
... if v is not None:
... results[k].append(v)
...
>>> results
defaultdict(<function <lambda> at 0x7f53d0992c08>, {'i': ['hij', 'hij'], 'b': ['abc', 'abc']})
>>> [m.groupdict() for m in re.finditer('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk')]
[{'i': None, 'b': 'abc'}, {'i': 'hij', 'b': None}]
Кажется, все работает нормально, хотя, если у вас есть много групп, проверяющих, какая из них не Нет
может стать утомительным.
Это находит все .b.
и все .i.
соответствует в строке. Если вы хотите быть уверены, что найден один из них, вам также придется проверить это вручную.