避免在正则表达式中转义字符
Avoid escaping characters in regex
我正在处理 POST 正文的内容,并希望提取每个键的值。我要解析的数据是:
s = b'----------------------------941135026682458398564529\r\nContent-Disposition: form-data; name="username"\r\n\r\nmyusername\r\n----------------------------941135026682458398564529\r\nContent-Disposition: form-data; name="password"\r\n\r\nmypassword\r\n----------------------------941135026682458398564529\r\nContent-Disposition: form-data; name="keyword"\r\n\r\nmykeyword\r\n----------------------------941135026682458398564529--\r\n'
我想通过使用Python的re
模块得到值myusername
、mypassword
和mykeyword
。出于这个原因,我生成了这个模式:
pattern = r'\bname=\"{}\"\r\n\r\n([^-]+)\r'
然后根据需要修改以匹配每个键:
username_pattern = re.compile(pattern.format("username"))
password_pattern = re.compile(pattern.format("password"))
keyword_pattern = re.compile(pattern.format("keyword"))
我面临的问题是所有反斜杠都被转义了,所以当我定义 pattern
时,我没有保留之前定义的值,而是 每个反斜杠都转义了:
'\bname=\"{}\"\\r\\n\\r\\n([^-]+)\\r'
然后,当我运行 <any of the compiled patterns>.search(s)
方法时没有匹配项。我已经测试了模式 here 并且它对每个关键字都按预期工作。我怎样才能避免这个反斜杠转义?而且,如果我问的是不必要的,我做错了什么?
原始字符串只影响文字的解析方式。字符串对象无法记住您输入的确切内容,因此当它向您显示反斜杠转义时,它向您显示的是非原始文字。
这三个是等价的:
>>> re.compile('\r', re.DEBUG)
LITERAL 13
>>> re.compile('\r', re.DEBUG)
LITERAL 13
>>> re.compile(r'\r', re.DEBUG)
LITERAL 13
但这不是:
>>> re.compile(r'\r', re.DEBUG)
LITERAL 92
LITERAL 114
您已经在使用 raw
前缀。所以不需要双重转义 \r
或 \n
否则它们将按字面意思(正则表达式接受文字 \n
或 \n
)。因此,唯一的问题仍然是您需要作为 raw
传递的 \b
字符:
pattern = r'\bname="{}"\r\n\r\n([^-]+)\r'
没有raw
的选择:
pattern = '\bname="{}"\r\n\r\n([^-]+)\r'
有了这些我就得到了与你的字符串的匹配(当我将它用作字符串而不是字节时)
我正在处理 POST 正文的内容,并希望提取每个键的值。我要解析的数据是:
s = b'----------------------------941135026682458398564529\r\nContent-Disposition: form-data; name="username"\r\n\r\nmyusername\r\n----------------------------941135026682458398564529\r\nContent-Disposition: form-data; name="password"\r\n\r\nmypassword\r\n----------------------------941135026682458398564529\r\nContent-Disposition: form-data; name="keyword"\r\n\r\nmykeyword\r\n----------------------------941135026682458398564529--\r\n'
我想通过使用Python的re
模块得到值myusername
、mypassword
和mykeyword
。出于这个原因,我生成了这个模式:
pattern = r'\bname=\"{}\"\r\n\r\n([^-]+)\r'
然后根据需要修改以匹配每个键:
username_pattern = re.compile(pattern.format("username"))
password_pattern = re.compile(pattern.format("password"))
keyword_pattern = re.compile(pattern.format("keyword"))
我面临的问题是所有反斜杠都被转义了,所以当我定义 pattern
时,我没有保留之前定义的值,而是 每个反斜杠都转义了:
'\bname=\"{}\"\\r\\n\\r\\n([^-]+)\\r'
然后,当我运行 <any of the compiled patterns>.search(s)
方法时没有匹配项。我已经测试了模式 here 并且它对每个关键字都按预期工作。我怎样才能避免这个反斜杠转义?而且,如果我问的是不必要的,我做错了什么?
原始字符串只影响文字的解析方式。字符串对象无法记住您输入的确切内容,因此当它向您显示反斜杠转义时,它向您显示的是非原始文字。
这三个是等价的:
>>> re.compile('\r', re.DEBUG)
LITERAL 13
>>> re.compile('\r', re.DEBUG)
LITERAL 13
>>> re.compile(r'\r', re.DEBUG)
LITERAL 13
但这不是:
>>> re.compile(r'\r', re.DEBUG)
LITERAL 92
LITERAL 114
您已经在使用 raw
前缀。所以不需要双重转义 \r
或 \n
否则它们将按字面意思(正则表达式接受文字 \n
或 \n
)。因此,唯一的问题仍然是您需要作为 raw
传递的 \b
字符:
pattern = r'\bname="{}"\r\n\r\n([^-]+)\r'
没有raw
的选择:
pattern = '\bname="{}"\r\n\r\n([^-]+)\r'
有了这些我就得到了与你的字符串的匹配(当我将它用作字符串而不是字节时)