Skip to content

Commit 53c7790

Browse files
committed
named groups
1 parent 329c356 commit 53c7790

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

tests/verbal_expressions_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,11 @@ def test_should_match_email_address(self):
135135
def test_should_match_url(self):
136136
self.exp = self.v.start_of_line().then('http').maybe('s').then('://').maybe('www.').word().then('.').word().maybe('/').end_of_line().regex()
137137
self.assertRegexpMatches('https://www.google.com/', self.exp, 'Not a valid email')
138+
139+
def test_should_find_named_groups(self):
140+
name = "Linus Torvalds"
141+
self.exp = self.v.start_of_line().word(name='first_name').then(' ').word(name='last_name').end_of_line().regex()
142+
match = self.exp.match(name)
143+
self.assertIsNotNone(match)
144+
self.assertTrue(match.group('first_name') == 'Linus')
145+
self.assertTrue(match.group('last_name') == 'Torvalds')

verbalexpressions/verbal_expressions.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33

44
def re_escape(fn):
5-
def arg_escaped(this, *args):
5+
def arg_escaped(this, *args, **kwargs):
66
t = [isinstance(a, VerEx) and a.s or re.escape(str(a)) for a in args]
7-
return fn(this, *t)
7+
return fn(this, *t, **kwargs)
88
return arg_escaped
99

10+
11+
def group(val, name=None):
12+
prefix = '?P<{0}>'.format(name) if name else ''
13+
return '(' + prefix + val + ')'
14+
1015

1116
class VerEx(object):
1217
'''
@@ -50,49 +55,49 @@ def source(self):
5055

5156
# ---------------------------------------------
5257

53-
def anything(self):
54-
return self.add('(.*)')
58+
def anything(self, name=None):
59+
return self.add(group('.*', name))
5560

5661
@re_escape
5762
def anything_but(self, value):
58-
return self.add('([^' + value + ']*)')
63+
return self.add(group('[^' + value + ']*'))
5964

6065
def end_of_line(self):
6166
return self.add('$')
6267

6368
@re_escape
6469
def maybe(self, value):
65-
return self.add("(" + value + ")?")
70+
return self.add(group(value) + "?")
6671

6772
def start_of_line(self):
6873
return self.add('^')
6974

7075
@re_escape
71-
def find(self, value):
72-
return self.add('(' + value + ')')
76+
def find(self, value, name=None):
77+
return self.add(group(value, name))
7378
then = find
7479

7580
# special characters and groups
7681

7782
@re_escape
7883
def any(self, value):
79-
return self.add("([" + value + "])")
84+
return self.add(group("[" + value + "]"))
8085
any_of = any
8186

8287
def line_break(self):
83-
return self.add(r"(\n|(\r\n))")
88+
return self.add(group(r"\n|(\r\n)"))
8489
br = line_break
8590

8691
@re_escape
8792
def range(self, *args):
8893
from_tos = [args[i:i+2] for i in range(0, len(args), 2)]
89-
return self.add("([" + ''.join(['-'.join(i) for i in from_tos]) + "])")
94+
return self.add(group("[" + ''.join(['-'.join(i) for i in from_tos]) + "]"))
9095

9196
def tab(self):
9297
return self.add(r'\t')
9398

94-
def word(self):
95-
return self.add(r"(\w+)")
99+
def word(self, name=None):
100+
return self.add(group(r"\w+", name))
96101

97102
def OR(self, value=None):
98103
''' `or` is a python keyword so we use `OR` instead. '''

0 commit comments

Comments
 (0)