【问题标题】:Python regex match fails with UTF-8 charactersPython 正则表达式匹配因 UTF-8 字符而失败
【发布时间】:2015-07-06 11:24:07
【问题描述】:

我有一个 selenium/python 项目,它使用正则表达式匹配来查找 html 元素。这些元素属性有时包括丹麦语/挪威语字符ÆØÅ。问题出在下面这个sn-p中:

if (re.match(regexp_expression, compare_string)):
    result = True
else :
    result = False

regex_expressioncompare_string 在执行正则表达式匹配之前被操纵。如果我在上面的代码 sn-p 执行之前打印它们,并打印结果,我会得到以下输出:

Regex_expression: [^log på$]
compare string: [log på]
result = false

我把括号放在上面以确保没有空格。它们只是打印语句的一部分,而不是字符串变量的一部分。

如果我尝试在单独的脚本中重现该问题,如下所示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re

regexp_expression  = "^log på$"
compare_string = "log på"

if (re.match(regexp_expression, compare_string)):
    print("result true")
    result = True
else :
    print("result = false")
    result = False

那么结果为真。

这怎么可能? 为了让它更奇怪,它更早地工作了,我不确定我编辑了什么,这让它变得繁荣......

正则表达式比较方法的完整模块如下。我自己没有对此进行编码,所以我不是 100% 熟悉所有替换语句和字符串操作的原因,但我认为这无关紧要,当我可以在匹配方法失败之前检查字符串时在底部...

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re

def regexp_compare(regexp_expression, compare_string):
    #final int DOTALL
    #try:    // include try catch for "PatternSyntaxException" while testing/including a new symbol in this method..

    #catch(PatternSyntaxException e):
    #    System.out.println("Regexp>>"+regexp_expression)
    #    e.printStackTrace()
    #*/


    if(not compare_string.strip() and (not regexp_expression.strip() or regexp_expression.strip().lower() == "*".lower()) or (regexp_expression.strip().lower() == ".*".lower())):
        print("return 1")
        return True                

    if(not compare_string or not regexp_expression):
        print("return 2")
        return False                

    regexp_expression = regexp_expression.lower()
    compare_string = compare_string.lower()

    if(not regexp_expression.strip()): 
        regexp_expression = ""

    if(not compare_string.strip() and (not regexp_expression.strip() or regexp_expression.strip().lower() == "*".lower()) or (regexp_expression.strip().lower() == ".*".lower())):
        regexp_expression = ""
    else:

        regexp_expression = regexp_expression.replace("\\","\\\\")
        regexp_expression = regexp_expression.replace("\\.","\\\\.")
        regexp_expression = regexp_expression.replace("\\*", ".*")
        regexp_expression = regexp_expression.replace("\\(", "\\\\(")
        regexp_expression = regexp_expression.replace("\\)", "\\\\)")           
        regexp_expression_arr = regexp_expression.split("|")
        regexp_expression = ""

        for i in range(0, len(regexp_expression_arr)):
            if(not(regexp_expression_arr[i].startswith("^"))):
                regexp_expression_arr[i] = "^"+regexp_expression_arr[i]

            if(not(regexp_expression_arr[i].endswith("$"))):
                regexp_expression_arr[i] = regexp_expression_arr[i]+"$"

            regexp_expression = regexp_expression_arr[i] if regexp_expression == "" else regexp_expression+"|"+regexp_expression_arr[i]  




    result = None        

    print("Regex_expression: [" + regexp_expression+"]")
    print("compare string: [" + compare_string+"]")

    if (re.match(regexp_expression, compare_string)):
        print("result true")
        result = True
    else :
        print("result = false")
        result = False

    print("return result")
    return result

【问题讨论】:

  • ^log på$ 不是很好地使用正则表达式。如果您没有模式,为什么不直接使用==
  • 问题是,就我而言,它与 ^*$ 是多余的,但这是用于多个匹配项的通用 util 类,我不是它的作者。我想在其他情况下使用正则表达式语法是有原因的。就像是否需要检查元素的完整类字符串中是否存在单个 html 类一样。这次我只是碰巧匹配按钮文本而不是类。
  • 刚刚意识到我弄错了正则表达式字符串的语法。我虽然它的意思是“以 OR 结尾”,但 OR 是一个 AND。我同意这是对正则表达式的浪费。我不知道他们为什么选择这样编码......

标签: python regex utf-8 special-characters


【解决方案1】:

您可能正在将 unicode 字符串与非 unicode 字符串进行比较。

例如,在下面:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re

regexp_expression  = "^log på$"
compare_string = u"log på"

if (re.match(regexp_expression, compare_string)):
    print("result true")
    result = True
else :
    print("result = false")
    result = False

您将得到输出 False。因此,您的操作中可能有一个点不是 unicode。

同样的错误也会导致以下结果:

regexp_expression  = u"^log på$"
compare_string = "log på"

【讨论】:

  • 这很棒。我只是使用了这种方法:stackoverflow.com/questions/4987327/…。原来我的正则表达式匹配是 unicode,而比较字符串是普通字符串。它们在被发送到 regex_compare 方法之前就已经是这样了。谢谢!
猜你喜欢
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多