summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@austin.rr.com>2023-04-18 21:25:53 -0500
committerptmcg <ptmcg@austin.rr.com>2023-04-18 21:25:53 -0500
commit59623c2cd2de437f0587a003ccab66a1d2adf8be (patch)
treeb30aa27e7983f858a48ecb47ce3614bd19ce37bc
parentcf4f1559503f0eb66343c96cb0144e86f68e9b1d (diff)
downloadpyparsing-git-59623c2cd2de437f0587a003ccab66a1d2adf8be.tar.gz
Fix regex matching for Python quoted strings
-rw-r--r--pyparsing/core.py8
-rw-r--r--tests/test_unit.py34
2 files changed, 38 insertions, 4 deletions
diff --git a/pyparsing/core.py b/pyparsing/core.py
index 4c68e8c..8ab6d41 100644
--- a/pyparsing/core.py
+++ b/pyparsing/core.py
@@ -6057,16 +6057,16 @@ quoted_string = Combine(
).set_name("quoted string using single or double quotes")
python_quoted_string = Combine(
- (Regex(r'"([^"]|""?(?!"))*', flags=re.MULTILINE) + '"""').set_name(
+ (Regex(r'"""(?:[^"\\]|""(?!")|"(?!"")|\\.)*', flags=re.MULTILINE) + '"""').set_name(
"multiline double quoted string"
)
- | (Regex(r"'([^']|''?(?!'))*", flags=re.MULTILINE) + "'''").set_name(
+ ^ (Regex(r"'''(?:[^'\\]|''(?!')|'(?!'')|\\.)*", flags=re.MULTILINE) + "'''").set_name(
"multiline single quoted string"
)
- | (Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"').set_name(
+ ^ (Regex(r'"(?:[^"\n\r\\]|(?:\\")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"').set_name(
"double quoted string"
)
- | (Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'").set_name(
+ ^ (Regex(r"'(?:[^'\n\r\\]|(?:\\')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'").set_name(
"single quoted string"
)
).set_name("Python quoted string")
diff --git a/tests/test_unit.py b/tests/test_unit.py
index 76e5826..1f75556 100644
--- a/tests/test_unit.py
+++ b/tests/test_unit.py
@@ -1321,6 +1321,40 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase):
print()
# fmt: on
+ def testPythonQuotedStrings(self):
+ success1, _ = pp.python_quoted_string.run_tests([
+ '"""xyz"""',
+ '''"""xyz
+ """''',
+ '"""xyz "" """',
+ '''"""xyz ""
+ """''',
+ '"""xyz " """',
+ '''"""xyz "
+ """''',
+ r'''"""xyz \"""
+
+ """''',
+ "'''xyz'''",
+ """'''xyz
+ '''""",
+ "'''xyz '' '''",
+ """'''xyz ''
+ '''""",
+ "'''xyz ' '''",
+ """'''xyz '
+ '''""",
+ r"""'''xyz \'''
+ '''""",
+ ])
+
+ print("\n\nFailure tests")
+ success2, _ = pp.python_quoted_string.run_tests([
+ '"xyz"""',
+ ], failure_tests=True)
+
+ self.assertTrue(success1 and success2, "Python quoted string matching failure")
+
def testCaselessOneOf(self):
caseless1 = pp.oneOf("d a b c aA B A C", caseless=True)
caseless1str = str(caseless1)