【问题标题】:How do I index multiple occurrences of a string that includes special characters? [duplicate]如何索引包含特殊字符的字符串的多次出现? [复制]
【发布时间】:2021-07-14 19:54:56
【问题描述】:

我正在加载一个使用特殊格式的数据文件,其中包括** 将文件分成多个部分。例如:**HEADER**COMMENTS**CONSTANTS**DATA都是文件中的节标题,每个节需要区别对待。所以我试图索引每个部分标题的位置,所有这些标题都以双星号开头。

我目前有:

Titles = [m.start() for m in re.finditer('e', mytxt)]

它索引文件中每个 e 的位置。然而:

Titles = [m.start() for m in re.finditer('**', mytxt)]

给我:

error: nothing to repeat

我也试过了:

Titles = [m.start() for m in re.finditer(r'**', mytxt)]

认为它会将搜索词转换为原始文本并停止尝试将 * 作为特殊字符处理,但它不起作用。

【问题讨论】:

标签: python


【解决方案1】:

问题是您需要转义那些星号用反斜杠!。简单地将它们放在原始字符串中不会做任何事情。

mytxt = """**HEADER
abc
def
**COMMENTS
ghi
jkl
**DATA
123
546
789"""

titles = [m.start() for m in re.finditer(r'\*\*', mytxt)]
print(titles) # gives [0, 17, 36]

如果您想确保它们位于行首,或者星号后面的内容应该是几个关键字之一,您可以将其添加到正则表达式中:

mytxt = """**HEADER
abc
def
**COMMENTS
ghi
jkl
**DATA
**junkheader
123**000
546**123
789"""

titles = [m.start() for m in re.finditer(r'\*\*', mytxt)]
print(titles) # gives [0, 17, 36, 43, 59, 68]

# But, 
titles = [m.start() for m in re.finditer(r'^\*\*', mytxt, re.MULTILINE)]
print(titles) # gives [0, 17, 36, 43]

# If you know valid titles beforehand
known_titles = ["HEADER", "COMMENTS", "CONSTANTS", "DATA"]
regex = r"^\*\*(" + "|".join(known_titles) + ")$"
print(regex) # Output: ^\*\*(HEADER|COMMENTS|CONSTANTS|DATA)$

titles = [m.start() 
     for m in re.finditer(regex, mytxt, re.MULTILINE)]
print(titles) # Gives [0, 17, 36]

re.MULTILINE 允许您将字符串中的换行字符识别为新行的开头。

正则表达式开头的^\*\* 中的^ 强制星号位于新行的开头。

所以这个正则表达式:^\*\*(HEADER|COMMENTS|CONSTANTS|DATA)$ 的意思是:

  • ^:匹配行首
  • \*\*:字面上是两个星号
  • (HEADER|COMMENTS|CONSTANTS|DATA):其中一个词
  • $:行尾

Try the regex at Regex101

【讨论】:

  • 哇,好用,谢谢!你能解释一下它为什么起作用吗?我得到 r 表示原始文本,但不应该然后搜索 ** 吗? \ 是什么意思?
  • 确保**开头的示例对我不起作用,因为它要求我已经知道标题标题。这些只是示例,但还有更多可接受的标题。用户可以添加自己的。
  • @GregorySmithUK 因为* 在正则表达式中有special meaning。要告诉正则表达式引擎您要匹配文字 *,您需要 转义 *。你用反斜杠来做到这一点。原始文本是 python 用于解析字符串中的反斜杠的功能,它与正则表达式或转义其他字符无关
  • @GregorySmithUK 我修改了行首的示例并添加了一些解释。您无需知道标题即可在行首匹配它们
猜你喜欢
  • 2015-05-20
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 2020-06-14
  • 2017-09-06
  • 1970-01-01
相关资源
最近更新 更多