簡體   English   中英

解析單引號或雙引號並允許使用正則表達式轉義字符(在Python中)

[英]Parsing single or double quotes and allow for escaped characters using regular expressions (in Python)

我的輸入看起來像一個參數列表:

input1 = '''
title="My First Blog" author='John Doe'
'''

值可以用單引號或雙引號括起來,但是,也允許轉義:

input2 = '''
title='John\'s First Blog' author="John Doe"
'''

有沒有辦法使用正則表達式來提取會計單引號或雙引號和轉義引號的鍵值對?

使用python,我可以使用以下正則表達式並處理非轉義引號:

rex = r"(\w+)\=(?P<quote>['\"])(.*?)(?P=quote)"

然后返回:

import re
re.findall(rex, input1)
[('title', '"', 'My First Blog'), ('author', "'", 'John Doe')]

import re
re.findall(rex, input2)
[('title', "'", 'John'), ('author', '"', 'John Doe')]

后者是不正確的。 我無法弄清楚如何處理轉義引號 - 假設在(。*?)部分。 我一直在使用Python正則表達式的已發布答案中的解決方案來匹配單引號中的文本,忽略轉義引號(和制表符/換行符)無濟於事。

從技術上講,我不需要findall來返回引號字符 - 而只需要鍵/值對 - 但這很容易處理。

任何幫助,將不勝感激! 謝謝!

我認為蒂姆使用反向引用過度復雜化表達式(並在此猜測)也使得速度變慢。 標准方法(在owl書中使用)是分別匹配單引號和雙引號字符串:

rx = r'''(?x)
    (\w+) = (
        ' (?: \\. | [^'] )* '
        |
        " (?: \\. | [^"] )* "
        |
        [^'"\s]+
    )
'''

添加一些后期處理,你很好:

input2 = r'''
title='John\'s First Blog' author="John Doe"
'''

data = {k:v.strip("\"\'").decode('string-escape') for k, v in re.findall(rx, input2)}
print data
# {'author': 'John Doe', 'title': "John's First Blog"}

作為獎勵,這也匹配未加引號的屬性,如weight=150

添加:這是一個沒有正則表達式的清潔方式:

input2 = r'''
title='John\'s First Blog' author="John Doe"
'''

import shlex

lex = shlex.shlex(input2, posix=True)
lex.escapedquotes = '\"\''
lex.whitespace = ' \n\t='
for token in lex:
    print token

# title
# John's First Blog
# author
# John Doe

編輯

我的初始正則表達式解決方案有一個錯誤。 該錯誤掩蓋了輸入字符串中的錯誤: input2不是您認為的錯誤:

>>> input2 = '''
... title='John\'s First Blog' author="John Doe"
... '''
>>> input2      # See - the apostrophe is not correctly escaped!
'\ntitle=\'John\'s First Blog\' author="John Doe"\n'  

你需要使input2成為一個原始字符串(或使用雙反斜杠):

>>> input2 = r'''
... title='John\'s First Blog' author="John Doe"
... '''
>>> input2
'\ntitle=\'John\\\'s First Blog\' author="John Doe"\n'

現在,您可以使用正確處理轉義引號的正則表達式:

>>> rex = re.compile(
    r"""(\w+)# Match an identifier (group 1)
    =        # Match =
    (['"])   # Match an opening quote (group 2)
    (        # Match and capture into group 3:
     (?:     # the following regex:
      \\.    # Either an escaped character
     |       # or
      (?!\2) # (as long as we're not right at the matching quote)
      .      # any other character.
     )*      # Repeat as needed
    )        # End of capturing group
    \2       # Match the corresponding closing quote.""", 
    re.DOTALL | re.VERBOSE)
>>> rex.findall(input2)
[('title', "'", "John\\'s First Blog"), ('author', '"', 'John Doe')]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM