summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-05-18 05:53:01 +0000
committerptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-05-18 05:53:01 +0000
commitb1465aaa68987b460f6e5e1e071212c8e2da07a9 (patch)
tree87740dd2dfdb8e459e3b772d205c0406eb119960
parent716ebc0404e409d9df026065bda931bf468f49b0 (diff)
downloadpyparsing-b1465aaa68987b460f6e5e1e071212c8e2da07a9.tar.gz
Added more expressions to pyparsing_common: IPv4 and IPv6 addresses (including long, short, and mixed forms of IPv6; MAC address; ISO8601 date and date time strings
git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@353 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b
-rw-r--r--src/CHANGES11
-rw-r--r--src/pyparsing.py26
-rw-r--r--src/unitTests.py83
3 files changed, 116 insertions, 4 deletions
diff --git a/src/CHANGES b/src/CHANGES
index d2aa8ad..b9f6a38 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -2,7 +2,16 @@
Change Log
==========
-Version 2.1.4 -
+Verison 2.1.5 -
+------------------------------
+- Added more expressions to pyparsing_common:
+ . IPv4 and IPv6 addresses (including long, short, and mixed forms
+ of IPv6
+ . MAC address
+ . ISO8601 date and date time strings
+
+
+Version 2.1.4 - May, 2016
------------------------------
- Split out the '==' behavior in ParserElement, now implemented
as the ParserElement.matches() method. Using '==' for string test
diff --git a/src/pyparsing.py b/src/pyparsing.py
index a4e016b..3383046 100644
--- a/src/pyparsing.py
+++ b/src/pyparsing.py
@@ -58,7 +58,7 @@ The pyparsing module handles some of the problems that are typically vexing when
"""
__version__ = "2.1.5"
-__versionTime__ = "14 May 2016 02:36 UTC"
+__versionTime__ = "18 May 2016 05:17 UTC"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@@ -3933,6 +3933,26 @@ class pyparsing_common:
identifier = Word(alphas+'_', alphanums+'_').setName("identifier")
"""typical code identifier"""
+
+ ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address")
+ "IPv4 address (C{0.0.0.0 - 255.255.255.255})"
+
+ _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}')
+ _full_ipv6_address = _ipv6_part + (':' + _ipv6_part)*7
+ _short_ipv6_address = Optional(_ipv6_part + (':' + _ipv6_part)*(0,7)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,7))
+ _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8)
+ _mixed_ipv6_address = "::ffff:" + ipv4_address
+ ipv6_address = Combine(_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")
+ "IPv6 address (long, short, or mixed form)"
+
+ mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address")
+ "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)"
+
+ iso8601_date = Regex(r'\d{4}(?:-\d\d(?:-\d\d)?)?').setName("ISO8601 date")
+ "ISO8601 date (C{yyyy-mm-dd})"
+
+ iso8601_datetime = Regex(r'\d{4}-\d\d-\d\dT\d\d:\d\d(:\d\d(\.\d*)?)?(Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime")
+ "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)})"
if __name__ == "__main__":
@@ -3984,7 +4004,7 @@ if __name__ == "__main__":
6.02e23
1e-12
""")
-
+
# any int or real number, returned as float
pyparsing_common.number.runTests("""
100
@@ -3994,4 +4014,4 @@ if __name__ == "__main__":
6.02e23
1e-12
""")
- \ No newline at end of file
+
diff --git a/src/unitTests.py b/src/unitTests.py
index b545af4..306455e 100644
--- a/src/unitTests.py
+++ b/src/unitTests.py
@@ -2626,6 +2626,89 @@ class RunTestsTest(ParseTestCase):
for res,expected in zip(results, expectedResults):
assert res == expected, "failed test: " + expected[0][2:]
+class CommonExpressionsTest(ParseTestCase):
+ def runTest(self):
+ from pyparsing import pyparsing_common
+
+ success = pyparsing_common.mac_address.runTests("""
+ AA:BB:CC:DD:EE:FF
+ AA.BB.CC.DD.EE.FF
+ AA-BB-CC-DD-EE-FF
+ """, printResults=False)[0]
+ assert success, "error in parsing valid MAC address"
+
+ success = pyparsing_common.mac_address.runTests("""
+ AA.BB:CC:DD:EE:FF
+ """, printResults=False)[0]
+ assert not success, "error in detecting invalid mac address"
+
+ success = pyparsing_common.ipv4_address.runTests("""
+ 0.0.0.0
+ 1.1.1.1
+ 127.0.0.1
+ 1.10.100.199
+ 255.255.255.255
+ """, printResults=False)[0]
+ assert success, "error in parsing valid IPv4 address"
+
+ success = pyparsing_common.ipv4_address.runTests("""
+ 256.255.255.255
+ """, printResults=False)[0]
+ assert not success, "error in detecting invalid IPv4 address"
+
+ success = pyparsing_common.ipv6_address.runTests("""
+ 2001:0db8:85a3:0000:0000:8a2e:0370:7334
+ 2134::1234:4567:2468:1236:2444:2106
+ 0:0:0:0:0:0:A00:1
+ 1080::8:800:200C:417A
+ ::A00:1
+ ::1
+ ::
+ ::ffff:192.168.0.1
+ """, parseAll=True, printResults=False)[0]
+ assert success, "error in parsing valid IPv6 address"
+
+ success = pyparsing_common.ipv6_address.runTests("""
+ 1080:0:0:0:8:800:200C
+ """, parseAll=True, printResults=False)[0]
+ assert not success, "error in detecting invalid IPv6 address"
+
+ success = pyparsing_common.numeric.runTests("""
+ 100
+ -100
+ +100
+ 3.14159
+ 6.02e23
+ 1e-12
+ """, parseAll=True, printResults=False)[0]
+ assert success, "error in parsing valid numerics"
+
+ # any int or real number, returned as float
+ success, results = pyparsing_common.number.runTests("""
+ 100
+ -100
+ +100
+ 3.14159
+ 6.02e23
+ 1e-12
+ """, parseAll=True, printResults=False)
+ assert success, "error in parsing valid numerics"
+
+ success = pyparsing_common.iso8601_date.runTests("""
+ 1997
+ 1997-07
+ 1997-07-16
+ """, parseAll=True, printResults=False)[0]
+ assert success, "error in parsing valid iso8601_date"
+
+ success = pyparsing_common.iso8601_datetime.runTests("""
+ 1997-07-16T19:20+01:00
+ 1997-07-16T19:20:30+01:00
+ 1997-07-16T19:20:30.45+01:00
+ """, parseAll=True, printResults=False)[0]
+ assert success, "error in parsing valid iso8601_datetime"
+
+
class MiscellaneousParserTests(ParseTestCase):
def runTest(self):
import pyparsing