【问题标题】:Searching a string and returning only things I specify搜索字符串并仅返回我指定的内容
【发布时间】:2012-04-04 02:29:34
【问题描述】:

希望这篇文章越来越好..

所以我坚持这个程序的这个功能,它将返回指定某个关键字的整个单词。

ie - 如果我告诉它在字符串“blah blah blah blah I=1mV blah blah etc?”中查找单词“I=”,它会返回找到它的整个单词,所以在这种情况下,它将返回 I=1mV。

我尝试了很多不同的方法,例如,

text = "One of the values, I=1mV is used"
print(re.split('I=', text))

但是,这会返回相同的字符串,但不包含 I,所以它会返回

['One of the values, ', '1mV is used']

如果我尝试正则表达式解决方案,我会遇到数字可能超过 1 位的问题,因此这段底部代码仅在数字为 1 位时才有效。如果 I=10mV 是那个值,它只会返回一个,但如果我有两次 [/0-9],则代码不再适用于只有 1 个值。

text = "One of the values, I=1mV is used"
print(re.findall("I=[/0-9]", text))

['I=1'] 

当我尝试使用 re.match 时,

text = "One of the values, I=1mV is used"
print(re.search("I=", text))

<_sre.SRE_Match object at 0x02408BF0>

什么是检索单词的好方法(在这种情况下,我想检索 I=1mV)并切掉字符串的其余部分?

【问题讨论】:

  • +1!记录在案 - 感谢您提出一个很好的问题。你已经说出了你想要的,展示了你尝试过的东西,并且通常表明你愿意学习。太棒了!

标签: python python-3.x


【解决方案1】:

更好的方法是先将文本拆分为单词:

>>> text = "One of the values, I=1mV is used"
>>> words = text.split()
>>> words
['One', 'of', 'the', 'values,', 'I=1mV', 'is', 'used']

然后过滤单词以找到您需要的单词:

>>> [w for w in words if 'I=' in w]
['I=1mV']

这将返回包含I= 的所有单词的列表。然后我们可以只取第一个找到的元素:

>>> [w for w in words if 'I=' in w][0]
'I=1mV'

完成!我们可以做一些清理工作的方法是只查找第一个匹配项,而不是检查每个单词。我们可以为此使用生成器表达式:

>>> next(w for w in words if 'I=' in w)
'I=1mV'

当然,您可以调整if 条件以更好地满足您的需求,例如,您可以使用str.startswith() 来检查单词是否以某个字符串开头,或者使用re.match() 来检查单词是否与模式匹配。

【讨论】:

  • 问题是,返回的值的类型是什么?是字符串还是列表?
  • @user:如果有方括号,就是一个列表。
【解决方案2】:

使用字符串方法

作为记录,您尝试将字符串分成两半,使用I= 作为分隔符,几乎是正确的。你可以使用str.partition(),而不是使用str.split(),它会丢弃分隔符。

>>> my_text = "Loadflow current was I=30.63kA"
>>> my_text.partition("I=")
('Loadflow current was ', 'I=', '30.63kA')

使用正则表达式

更灵活和健壮的解决方案是使用正则表达式:

>>> import re
>>> pattern = r"""
... I=             # specific string "I="
... \s*            # Possible whitespace
... -?             # possible minus sign
... \s*            # possible whitespace
... \d+            # at least one digit
... (\.\d+)?       # possible decimal part
... """
>>> m = re.search(pattern, my_text, re.VERBOSE)
>>> m
<_sre.SRE_Match object at 0x044CCFA0>
>>> m.group()
'I=30.63'

这说明了更多的可能性(负数、整数或十进制数)。

注意使用:

  • 量词表示你想要的每件事有多少。
    • a* - 零个或多个 as
    • a+ - 至少一个a
    • a? - “可选” - 1 或 0 as
  • 带有 cmets 的详细正则表达式(re.VERBOSE 标志) - 比非详细等效 I=\s?-?\s?\d+(\.\d+) 更容易理解上述模式。
  • 正则表达式模式的原始字符串,r"..." 而不是普通字符串"..." - 意味着不必转义文字反斜杠。此处不需要,因为我们的模式不使用反斜杠,但有一天您需要匹配 C:\Program Files\...,而那一天您将需要原始字符串。

练习

  • 练习 1:如何扩展它以使其也能匹配单位?以及如何扩展它以使其可以与mAAkA 匹配?提示:“交替运算符”。

  • 练习 2:如何扩展它以匹配工程符号中的数字,即“1.00e3”或“-3.141e-4”?

【讨论】:

  • 感谢您的回答。大大拓宽了我的理解。
【解决方案3】:
import re
text = "One of the values, I=1mV is used"
l = (re.split('I=', text))
print str(l[1]).split(' ') [0]

如果您有多个I=,请对 l 中的每个奇数索引执行上述操作,因为 0 是第一个。

这是一个好方法,因为可以写“其中一个值,使用 I=1mV” 我猜你想知道我是 1mv。

顺便说一句,我是电流,它的单位是安培而不是伏特:)

【讨论】:

    【解决方案4】:

    在您的 re.findall 尝试中,您可能想要添加一个 +,这意味着一个或多个。
    下面是一些例子:

    import re
    
    test = "This is a test with I=1mV, I=1.414mv, I=10mv and I=1.618mv."
    
    result = re.findall(r'I=[\d\.]+m[vV]', test)
    
    print(result)
    
    test = "One of the values, I=1mV is used"
    
    result = re.search(r'I=([\d\.]+m[vV])', test)
    
    print(result.group(1))
    

    第一个打印是:['I=1mV', 'I=1.414mv', 'I=10mv', 'I=1.618mv']

    我已在 re.search 示例中对除 I= 以外的所有内容进行了分组,
    所以第二个打印是:1mV
    如果您有兴趣提取它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      相关资源
      最近更新 更多