首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在特定条件下替换Python中的字母

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

Stack Overflow用户
提问于 2015-05-06 14:43:57
回答 2查看 230关注 0票数 4

原始代码:

代码语言:javascript
复制
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)

产出如下:

代码语言:javascript
复制
 tuberculin 1 Cap(s)
 tylenol 1 Cap(s)
 tramadol 2 1 Cap(s)

我试图用“Caps”替换所有的药物为"1 Caps“--前2种药物是正确的--但是第3种药物的结果是”曲马多2 1 Caps“。

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-06 14:54:36

您可以在re模块 中使用正则表达式

代码语言:javascript
复制
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

以上打印

代码语言:javascript
复制
['tuberculin 1 Cap(s)', 'tylenol 1 Cap(s)', 'tramadol 2 Cap(s)']

按的要求打破了它

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

代码语言:javascript
复制
lst = ["one", "two", "three"]
print [element for element in lst]

这个打印['one', 'two', 'three']

现在转到正则表达式.

  • 正则表达式中的方括号(集合)意思是“选择内的任何字符”。因此,set [ab]将匹配ab
  • 在集合中,您可以有范围。[a-e]匹配从ae (包括)的任何字符。
  • regex中的+表示“左边的一个或多个东西”--因此,[ab]+将匹配1或多个a's和/或b的任何组合。
  • \d匹配任何数字(可以用0-9替换)。
  • 在regex中有特殊含义的任何字符--如“()”或“)”--都必须是转义或放在方括号中才能匹配。

我的正则表达式有三个主要部分:[a-z]+\d+Cap\(s\)。将它们结合在一起:

“任何一个或多个字母的组合,后面跟着空格”+“一个或多个数字,后面跟着空格”+“文本‘(S)’”。

re.findall(pattern, string)返回一个列表,其中包含与patternstring中找到的所有匹配项。因此,它的长度是0,意味着没有匹配。在你的例子中,这意味着没有“药物名称+ number +‘Cap’”。

虽然您可以通过检查字符串是否包含任何数字来实现相同的输入,但这确保它遵循"word + number +‘Cap“的显式模式。

允许药物名称中的数字

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

使用for循环的

如果您想在不使用列表理解的情况下更清楚地编写代码,可以使用常规的for循环:

代码语言:javascript
复制
for index, med in enumerate(meds):
  if len(re.findall("[a-zA-Z\d]+ \d+ Cap\(s\)", med)) == 0:
    meds[index] = med.replace(" Cap(s)", " 1 Cap(s)")

注意,要在for循环中更改列表中的值,您需要要更改的元素的索引(因此是枚举)。如果您对enumerate感到困惑,可以这样编写:

代码语言:javascript
复制
for i in xrange(len(meds)):
  if len(re.findall("[a-zA-Z\d]+ \d+ Cap\(s\)", meds[i])) == 0:
    meds[i] = meds[i].replace(" Cap(s)", " 1 Cap(s)")

枚举

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

票数 1
EN

Stack Overflow用户

发布于 2015-05-06 15:17:15

使用列表理解

代码语言:javascript
复制
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)']
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30080047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档