Regex 无法匹配字符串文字';{*}';通过为每个特殊字符转义\使用正则表达式

Regex 无法匹配字符串文字';{*}';通过为每个特殊字符转义\使用正则表达式,regex,python-3.x,special-characters,Regex,Python 3.x,Special Characters,我正在使用Python正则表达式,并希望创建一个正则表达式来匹配以下字符串文字: str = "JP 0.9300{*}%PEMULT% /" 我使用的正则表达式是: (^JP\s)(.+?)(\{\*\}%PEMULT%)(\s/$) 但上述正则表达式似乎对我不起作用,并以一个错误结尾,即: KeyError: '\\*\\' 我相信这是因为我试图将特殊字符'{*}'与我的正则表达式匹配 有人能看看正则表达式并建议如何格式化它以匹配特殊字符'{*} 更新代码和错误如下 完整代码: 重

我正在使用Python正则表达式,并希望创建一个正则表达式来匹配以下字符串文字:

str = "JP 0.9300{*}%PEMULT% /"
我使用的正则表达式是:

(^JP\s)(.+?)(\{\*\}%PEMULT%)(\s/$)
但上述正则表达式似乎对我不起作用,并以一个错误结尾,即:

 KeyError: '\\*\\'
我相信这是因为我试图将特殊字符
'{*}'
与我的正则表达式匹配

有人能看看正则表达式并建议如何格式化它以匹配特殊字符
'{*}


更新代码和错误如下

完整代码:
重新导入
str=”“”
生成日期:海燕
2017年11月1日/
/
GEFAC——生成:海燕
JP 0.9260{*}%PEMULT%/
JI 0.9260{*}%PEMULT%/
/
"""
date=“1\sNOV\s2017”
pe=“0.7000”
正则表达式=r“”
(^DATES[^\d.]+?{0}.+?GEFAC.+?JP\s)#Group1-从日期到JP\s的字符串
(.+?)#第2组-JP PE
(\{\*\}%PEMULT%)\\第3组-%PEMULT%修饰符
(.+?)#组4
(JI\s)第5组
(.+?)#第6组-吉普
(\{\*\}%PEMULT%)\\组7-%PEMULT%修饰符
(\s/$)#第8组-尾随“/”
“”格式(日期)
p=re.compile(regex,re.DOTALL | re.VERBOSE | re.MULTILINE)
str=p.sub('\g{0}\g\g\g{1}\g\g'.格式(pe,pe),str)
打印(str)
错误:
C:\appl\Python\3.2.1\Python.exe I:/Private/nabm/Python/regex/test.py
回溯(最近一次呼叫最后一次):
文件“I:/Private/nabm/python/regex/test.py”,第33行,在
“”格式(日期)
键错误:'\\*\\\'
进程已完成,退出代码为1
str.format()
使用大括号来标识它应该替换的字符串部分。如果字符串包含大括号,例如因为它表示正则表达式,则可能会发生冲突

可以通过向大括号中添加额外转义来解决冲突(请参阅
str.format()
)的文档),但这会使查看正则表达式中发生的情况变得更加困难,并且无法在诸如regex101.com之类的外部工具中对其进行测试

简而言之,在正则表达式上使用
str.format()
是一个全面的坏主意,建议在这种情况下完全避免使用它

我还建议不要将变量命名为内置类型。
str
不应用作变量名。我已将
date
重命名为
date\u expr
,以表示它不包含日期,而是包含与日期匹配的正则表达式。出于同样的原因,我将其设置为原始字符串

import re

input_str = """
DATES                                  -- Generated : Petrel
  1 NOV 2017 /
  /

GEFAC                                  -- Generated : Petrel
  JP 0.9260{*}%PEMULT% /
  JI 0.9260{*}%PEMULT% /
  /
  """

date_expr = r"1\sNOV\s2017"
pe = "0.7000"


entry_expr = r"""
(^DATES[^\d.]+?""" + date_expr + """.+?GEFAC.+?JP\s)    #Group1 - String from DATES through JP\s
(.+?)                                                   #Group2 - JP PE
(\{\*\}%PEMULT%)                                        #Group3 - %PEMULT% Modifier
(.+?)                                                   #Group4
(JI\s)                                                  #Group5
(.+?)                                                   #Group6 - JI PE
(\{\*\}%PEMULT%)                                        #Group7 - %PEMULT% Modifier
 (\s/$)                                                 #Group8 - Trailing " /"
"""

p = re.compile(entry_expr, re.DOTALL | re.VERBOSE | re.MULTILINE)
result = p.sub('\g<1>{0}\g<3>\g<4>\g<5>{1}\g<7>\g<8>'.format(pe, pe), input_str)

print(result)
重新导入
输入_str=”“”
生成日期:海燕
2017年11月1日/
/
GEFAC——生成:海燕
JP 0.9260{*}%PEMULT%/
JI 0.9260{*}%PEMULT%/
/
"""
日期\u expr=r“1\sNOV\s2017”
pe=“0.7000”
条目_expr=r”“”
(^DATES[^\d.]+?“+date_expr+”+?GEFAC.+?JP\s)#Group1-从日期到JP\s的字符串
(.+?)#第2组-JP PE
(\{\*\}%PEMULT%)\\第3组-%PEMULT%修饰符
(.+?)#组4
(JI\s)第5组
(.+?)#第6组-吉普
(\{\*\}%PEMULT%)\\组7-%PEMULT%修饰符
(\s/$)#第8组-尾随“/”
"""
p=re.compile(条目_expr,re.DOTALL | re.VERBOSE | re.MULTILINE)
result=p.sub('\g{0}\g\g\g{1}\g\g'。格式(pe,pe),输入
打印(结果)

在替换字符串中使用
str.format()
原则上是可以的,但不是超级可读的。我个人会使用
'\g'+pe+'\g\g'+pe+'\g\g'

问题确实在于python的
str.format()
,而在字符串中转义大括号的答案是:

如果需要在文本中包含大括号字符,可以通过加倍:{{和}}对其进行转义

因此,为了正确地
format()
您的正则表达式,您需要编写
({\*}%PEMULT%)
而不是
(\{\*}%PEMULT%)

以下是修改后的脚本:

#!/usr/bin/env python

import re


s = """
DATES                                  -- Generated : Petrel
  1 NOV 2017 /
  /

GEFAC                                  -- Generated : Petrel
  JP 0.9260{*}%PEMULT% /
  JI 0.9260{*}%PEMULT% /
  /
  """

date = "1\sNOV\s2017"
pe = "0.7000"


regex = r"""
(^DATES[^\d.]+?{0}.+?GEFAC.+?JP\s)                      #Group1 - String from DATES through JP\s
(.+?)                                                   #Group2 - JP PE
({{\*}}%PEMULT%)                                        #Group3 - %PEMULT% Modifier
(.+?)                                                   #Group4
(JI\s)                                                  #Group5
(.+?)                                                   #Group6 - JI PE
({{\*}}%PEMULT%)                                         #Group7 - %PEMULT% Modifier
 (\s/$)                                                 #Group8 - Trailing " /"
""".format(date)

p = re.compile(regex, re.DOTALL | re.VERBOSE | re.MULTILINE)
s = p.sub('\g<1>{0}\g<3>\g<4>\g<5>{1}\g<7>\g<8>'.format(pe, pe), s)
print(s)

作为旁注,Tomalak已经写过:注意不要使用保留关键字,如
str
,作为变量名。

显示Python代码。I.甚至使用。请参阅一些信息。您是否尝试使用两个反斜杠?有时您会遇到这样的问题:一种语言使用反斜杠来转义字符串中的字符,并且希望使用f最后生成的正则表达式包含反斜杠,因此您必须用第二个反斜杠来转义反斜杠。这里没有正则表达式问题。您有一个问题。(您可能也有正则表达式问题,我建议编写结构化解析器,而不是非常复杂的正则表达式,但这是另一回事。)使用
regex=r{\*}“
而不是
regex=r”\{\*\}”
。不要逃避大括号。如果你使用的是
format
,你可以利用参数索引,只提供
pe
一次:
“\g{0}\g\g\g{0}\g\g”。format(pe)
@ChristianKönig我知道,我也想过要注意这一点。但事实上,这只是对我一开始都不会做的事情的一个小小的优化。字符串插值在正则表达式领域中不起作用,它会损害表达式的可读性,同时不会给代码添加任何实际值。
import re

input_str = """
DATES                                  -- Generated : Petrel
  1 NOV 2017 /
  /

GEFAC                                  -- Generated : Petrel
  JP 0.9260{*}%PEMULT% /
  JI 0.9260{*}%PEMULT% /
  /
  """

date_expr = r"1\sNOV\s2017"
pe = "0.7000"


entry_expr = r"""
(^DATES[^\d.]+?""" + date_expr + """.+?GEFAC.+?JP\s)    #Group1 - String from DATES through JP\s
(.+?)                                                   #Group2 - JP PE
(\{\*\}%PEMULT%)                                        #Group3 - %PEMULT% Modifier
(.+?)                                                   #Group4
(JI\s)                                                  #Group5
(.+?)                                                   #Group6 - JI PE
(\{\*\}%PEMULT%)                                        #Group7 - %PEMULT% Modifier
 (\s/$)                                                 #Group8 - Trailing " /"
"""

p = re.compile(entry_expr, re.DOTALL | re.VERBOSE | re.MULTILINE)
result = p.sub('\g<1>{0}\g<3>\g<4>\g<5>{1}\g<7>\g<8>'.format(pe, pe), input_str)

print(result)
#!/usr/bin/env python

import re


s = """
DATES                                  -- Generated : Petrel
  1 NOV 2017 /
  /

GEFAC                                  -- Generated : Petrel
  JP 0.9260{*}%PEMULT% /
  JI 0.9260{*}%PEMULT% /
  /
  """

date = "1\sNOV\s2017"
pe = "0.7000"


regex = r"""
(^DATES[^\d.]+?{0}.+?GEFAC.+?JP\s)                      #Group1 - String from DATES through JP\s
(.+?)                                                   #Group2 - JP PE
({{\*}}%PEMULT%)                                        #Group3 - %PEMULT% Modifier
(.+?)                                                   #Group4
(JI\s)                                                  #Group5
(.+?)                                                   #Group6 - JI PE
({{\*}}%PEMULT%)                                         #Group7 - %PEMULT% Modifier
 (\s/$)                                                 #Group8 - Trailing " /"
""".format(date)

p = re.compile(regex, re.DOTALL | re.VERBOSE | re.MULTILINE)
s = p.sub('\g<1>{0}\g<3>\g<4>\g<5>{1}\g<7>\g<8>'.format(pe, pe), s)
print(s)
DATES                                  -- Generated : Petrel
  1 NOV 2017 /
  /

GEFAC                                  -- Generated : Petrel
  JP 0.7000{*}%PEMULT% /
  JI 0.7000{*}%PEMULT% /
  /