在特定条件下替换 Python 中的字母

  • 本文关键字:Python 替换 条件下 python
  • 更新时间 :
  • 英文 :

原始代码:
meds = [ "tuberculin Cap(s)", "tylenol Cap(s)", "tramadol 2 Cap(s)"]

for i in meds:
new_meds = i.replace(" Cap(s)", " 1 Cap(s)")
print(new_meds)
输出为:
tuberculin 1 Cap(s)
tylenol 1 Cap(s)
tramadol 2 1 Cap(s)

我正在尝试将所有药物替换为"大写"成"1 大写" 前 2 种药物是正确的,但第 3 种药物的结果是"曲马多 2 1 帽"。

我应该如何更正我的脚本,以便字符串中带有数字的所有药物都不会被修改?

最终结果应该是只有像"结核菌素帽"、"泰诺帽"这样的药物被修改,而不是"曲马多 2 帽"。

您可以将正则表达式与 re 模块一起使用:

import re
meds = [ "tuberculin Cap(s)", "tylenol Cap(s)", "tramadol 2 Cap(s)"]
meds = [med.replace(" Cap(s)", " 1 Cap(s)") if len(re.findall("[a-zA-Z]+ d+ Cap(s)", med)) == 0 else med for med in meds]
print meds

以上打印

['tuberculin 1 Cap(s)', 'tylenol 1 Cap(s)', 'tramadol 2 Cap(s)']

分解一下,如问

您似乎不熟悉列表推导。在python中,任何可迭代对象都可以循环,就像你对for循环所做的那样。此外,您还可以使用列表推导式:

lst = ["one", "two", "three"]
print [element for element in lst]

这将打印['one', 'two', 'three'].

现在来看正则表达式。

  • 正则表达式中的方括号(集)表示"选择里面的任何字符"。因此,集合[ab]将同时匹配ab

  • 在集合中,您可以有范围。[a-e]匹配从ae(含)的任何字符。

  • 正则表达式中的+意味着"左侧的一个或多个事物" - 因此[ab]+匹配一个或多个 a 和/或 b 的任意组合。

  • d匹配任何数字(可替换为 [0-9])。

  • 任何在正则表达式中具有特殊含义的字符 - 如表示组的">("或">)" - 必须转义或放在方括号内才能匹配。

我的正则表达式有三个主要部分;[a-z]+d+Cap(s)。组合它们匹配:

">

1 个或多个字母后跟一个空格的任意组合"+"一个或多个数字后跟一个空格">+"文本'Cap(s)'"。

re.findall(pattern, string)返回一个列表,其中包含与string中找到的pattern的所有匹配项。因此,它的长度0意味着没有匹配项。在您的情况下,这意味着没有"药物名称+编号+'帽子'"。

虽然您只需检查字符串是否包含任何数字即可实现此输入的相同效果,但这可确保它遵循"单词 + 数字 + 'Cap(s)'"的显式模式。

允许在药物名称中使用数字

如果你想允许任何序列作为药物名称(例如带有数字的分子式),你可以将正则表达式更改为[a-zA-Zd]+ d+ Cap(s),允许任何小写或大写字母以及数字成为名称的一部分。

使用 for 循环

如果你想在不使用列表推导的情况下更清楚地编写代码,你可以使用常规的for循环来实现:

for index, med in enumerate(meds):
if len(re.findall("[a-zA-Zd]+ d+ Cap(s)", med)) == 0:
meds[index] = med.replace(" Cap(s)", " 1 Cap(s)")

请注意,要在for循环中更改列表中的值,您需要要更改的元素的索引(因此需要枚举)。如果你觉得enumerate令人困惑,可以这样写:

for i in xrange(len(meds)):
if len(re.findall("[a-zA-Zd]+ d+ Cap(s)", meds[i])) == 0:
meds[i] = meds[i].replace(" Cap(s)", " 1 Cap(s)")

枚举

要扩展 for 循环中enumerate函数的使用,请执行以下操作:enumerate返回一个元组列表,其中包含列表中的索引(或任何序列)以及元素:(index, element)。在python中,你可以解压缩元组中的值:a,b = (1,2)a现在1b2

使用列表理解

In [35]: meds
Out[35]: ['tuberculin Cap(s)', 'tylenol Cap(s)', 'tramadol 2 Cap(s)']
In [36]: new_meds=[ i.replace(" Cap(s)", " 1 Cap(s)") if any(char.isdigit() for char in i) == False  else i for i in meds]
In [37]: new_meds
Out[37]: ['tuberculin 1 Cap(s)', 'tylenol 1 Cap(s)', 'tramadol 2 Cap(s)']

你可以这样使用正则表达式:

import re
meds = [ "tuberculin Cap(s)", "tylenol Cap(s)", "tramadol 2 Cap(s)"]
for i in meds:
if not re.match(".+d.+", i):
new_meds = i.replace(" Cap(s)", " 1 Cap(s)")
else:
new_meds = i
print(new_meds)

输出:

tuberculin 1 Cap(s)
tylenol 1 Cap(s)
tramadol 2 Cap(s)

表达式".+d.+"将找到具有"某物+数字+某物"的项目。

最新更新