Skip to content

Commit

Permalink
Fix using digit field numbering and types
Browse files Browse the repository at this point in the history
closes #125
  • Loading branch information
r1chardj0n3s committed Jan 14, 2021
1 parent 1269006 commit 5bc22a4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 18 deletions.
22 changes: 16 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,15 @@ Some simple parse() format string examples:
>>> parse("Bring me a {}", "Bring me a shrubbery")
<Result ('shrubbery',) {}>
>>> r = parse("The {} who say {}", "The knights who say Ni!")
>>> r = parse("The {} who {} {}", "The knights who say Ni!")
>>> print(r)
<Result ('knights', 'Ni!') {}>
<Result ('knights', 'say', 'Ni!') {}>
>>> print(r.fixed)
('knights', 'Ni!')
('knights', 'say', 'Ni!')
>>> print(r[0])
knights
>>> print(r[1:])
('say', 'Ni!')
>>> r = parse("Bring out the holy {item}", "Bring out the holy hand grenade")
>>> print(r)
<Result () {'item': 'hand grenade'}>
Expand All @@ -93,8 +97,11 @@ Some simple parse() format string examples:
>>> 'item' in r
True
Note that ``in`` only works if you have named fields. Dotted names and indexes
are possible though the application must make additional sense of the result:
Note that `in` only works if you have named fields.

Dotted names and indexes are possible with some limits. Only word identifiers
are supported (ie. no numeric indexes) and the application must make additional
sense of the result:

.. code-block:: pycon
Expand Down Expand Up @@ -377,6 +384,9 @@ the pattern, the actual match represents the shortest successful match for

----

- 1.19.0 Added slice access to fixed results (thanks @jonathangjertsen).
Also corrected matching of *full string* vs. *full line* (thanks @giladreti)
Fix issue with using digit field numbering and types
- 1.18.0 Correct bug in int parsing introduced in 1.16.0 (thanks @maxxk)
- 1.17.0 Make left- and center-aligned search consume up to next space
- 1.16.0 Make compiled parse objects pickleable (thanks @martinResearch)
Expand Down Expand Up @@ -453,5 +463,5 @@ the pattern, the actual match represents the shortest successful match for
and removed the restriction on mixing fixed-position and named fields
- 1.0.0 initial release
This code is copyright 2012-2020 Richard Jones <[email protected]>
This code is copyright 2012-2021 Richard Jones <[email protected]>
See the end of the source file for the license of use.
33 changes: 21 additions & 12 deletions parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@
>>> 'item' in r
True
Note that `in` only works if you have named fields. Dotted names and indexes
are possible though the application must make additional sense of the result:
Note that `in` only works if you have named fields.
Dotted names and indexes are possible with some limits. Only word identifiers
are supported (ie. no numeric indexes) and the application must make additional
sense of the result:
.. code-block:: pycon
Expand Down Expand Up @@ -381,7 +384,9 @@
----
- 1.19.0 Added slice access to fixed results (thanks @jonathangjertsen)
- 1.19.0 Added slice access to fixed results (thanks @jonathangjertsen).
Also corrected matching of *full string* vs. *full line* (thanks @giladreti)
Fix issue with using digit field numbering and types
- 1.18.0 Correct bug in int parsing introduced in 1.16.0 (thanks @maxxk)
- 1.17.0 Make left- and center-aligned search consume up to next space
- 1.16.0 Make compiled parse objects pickleable (thanks @martinResearch)
Expand Down Expand Up @@ -458,13 +463,13 @@
and removed the restriction on mixing fixed-position and named fields
- 1.0.0 initial release
This code is copyright 2012-2020 Richard Jones <[email protected]>
This code is copyright 2012-2021 Richard Jones <[email protected]>
See the end of the source file for the license of use.
'''

from __future__ import absolute_import

__version__ = '1.18.0'
__version__ = '1.19.0'

# yes, I now have two problems
import re
Expand Down Expand Up @@ -1032,11 +1037,17 @@ def _handle_field(self, field):
# now figure whether this is an anonymous or named field, and whether
# there's any format specification
format = ''
if field and field[0].isalpha():
if ':' in field:
name, format = field.split(':')
else:
name = field

if ':' in field:
name, format = field.split(':')
else:
name = field

# This *should* be more flexible, but parsing complicated structures
# out of the string is hard (and not necessarily useful) ... and I'm
# being lazy. So for now `identifier` is "anything starting with a
# letter" and digit args don't get attribute or element stuff.
if name and name[0].isalpha():
if name in self._name_to_group_map:
if self._name_types[name] != format:
raise RepeatedNameError(
Expand All @@ -1056,8 +1067,6 @@ def _handle_field(self, field):
else:
self._fixed_fields.append(self._group_index)
wrap = r'(%s)'
if ':' in field:
format = field[1:]
group = self._group_index

# simplest case: no type specifier ({} or {name})
Expand Down
6 changes: 6 additions & 0 deletions test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ def test_named_typed(self):
self._test_expression('{name:w}', r'(?P<name>\w+)')
self._test_expression('{name:w} {other:w}', r'(?P<name>\w+) (?P<other>\w+)')

def test_numbered(self):
self._test_expression('{0}', r'(.+?)')
self._test_expression('{0} {1}', r'(.+?) (.+?)')
self._test_expression('{0:f} {1:f}', r'([-+ ]?\d*\.\d+) ([-+ ]?\d*\.\d+)')

def test_bird(self):
# skip some trailing whitespace
self._test_expression('{:>}', r' *(.+?)')
Expand Down Expand Up @@ -1076,6 +1081,7 @@ def test_int_convert_stateless_base(self):
self.assertEqual(parser.parse("1234")[0], 1234)
self.assertEqual(parser.parse("0b1011")[0], 0b1011)


if __name__ == '__main__':
unittest.main()

Expand Down

0 comments on commit 5bc22a4

Please sign in to comment.