【问题标题】:Check if string begins with one of several substrings in Python检查字符串是否以 Python 中的几个子字符串之一开头
【发布时间】:2015-11-06 18:54:43
【问题描述】:

我不知道如何为一组子字符串执行line.startswith("substring"),所以我尝试了底部代码的一些变体:因为我拥有已知的 4 个字符开头的子字符串,但我很确定我的语法错误,因为这不会拒绝任何行。

(上下文:我的目标是在读取文件时丢弃标题行。标题行以一组有限的字符串开头,但我不能只检查任何地方的子字符串,因为有效的内容行可能包含关键字后面的字符串。)

cleanLines = []
line = "sample input here"
if not line[0:3] in ["node", "path", "Path"]:  #skip standard headers
    cleanLines.append(line)

【问题讨论】:

  • 字符串切片的结束索引是排他的。你想要line[0:4] 或只是line[:4]
  • Annnnd 这就是全部。固定的。如果你把它作为答案,我会立即选择它。
  • 如果您知道如何使用长度不敏感的startswith() 来实现,我将不胜感激。我讨厌脆弱的黑客攻击。
  • .startswith() 调用“开始子字符串”前缀

标签: string python-3.x set


【解决方案1】:

您的问题源于字符串切片不包括停止索引:

In [7]: line = '0123456789'

In [8]: line[0:3]
Out[8]: '012'

In [9]: line[0:4]
Out[9]: '0123'

In [10]: line[:3]
Out[10]: '012'

In [11]: line[:4]
Out[11]: '0123'

ij 之间分割字符串会返回从i 开始到j 结束(但不包括)的子字符串。

为了让您的代码运行得更快,您可能希望以集合而不是列表的形式测试成员资格:

cleanLines = []
line = "sample input here"
blacklist = set(["node", "path", "Path"])
if line[:4] not in blacklist:  #skip standard headers
    cleanLines.append(line)

现在,您实际使用该代码执行的是startswith,它不受任何长度参数的限制:

In [12]: line = '0123456789'

In [13]: line.startswith('0')
Out[13]: True

In [14]: line.startswith('0123')
Out[14]: True

In [15]: line.startswith('03')
Out[15]: False

所以你可以这样做来排除标题:

cleanLines = []
line = "sample input here"
headers = ["node", "path", "Path"]
if not any(line.startswith(header) for header in headers) :  #skip standard headers
    cleanLines.append(line)

【讨论】:

  • 也可以使用我觉得很酷的any(map(line.startswith, headers))
  • 以上和答案中的都不是必需的。 startswith 也可以带一个元组的选项,所以它可以是if not line.startswith(tuple(headers)):
猜你喜欢
  • 2011-05-04
  • 2022-11-16
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 2017-11-27
  • 2011-06-13
  • 2011-12-07
  • 2023-01-01
相关资源
最近更新 更多