在Python中,我试图找到与给定模式匹配的任意字符串的最后一个位置,该模式被指定为负字符集regex模式。例如,由于字符串uiae1iuae200
,并且not的模式是一个数字(Python中的regex模式是[^0-9]
),因此我需要'8'('200之前的最后一个'e')。在
What is the most pythonic way to achieve this?
由于在Python文档中快速找到方法文档和最适合的方法有点棘手(由于方法文档位于相应页面的中间位置,比如re page中的re.search()
),所以我很快发现自己最好的方法就是使用re.search()
-但是当前的表单必须是次优的方法信息技术:
import re
string = 'uiae1iuae200' # the string to investigate
len(string) - re.search(r'[^0-9]', string[::-1]).start()
我对此不满意有两个原因:
-a)在与[::-1]
一起使用之前,我需要反转string
,并且
-b)我还需要反转得到的位置(从len(string)
中减去它,因为之前已经颠倒了字符串。在
需要有更好的方法来实现这一点,即使结果是re.search()
。在
我知道re.search(...).end()
超过了.start()
,但是{.start()
,.end()
等,似乎总是匹配第一个组,而第一个组没有关于最后一个匹配的位置信息。然而,选择组似乎首先需要将返回值临时保存在变量中(这会阻止简洁的一行程序),因为我需要访问有关选择最后一个组的信息,然后从该组中选择.end()
。在
你的Python疗法是什么?比起拥有最优化的运行时,我更看重pythonic。在
更新
该解决方案也应在角落情况下起作用,如123
(没有与regex匹配的位置)、空字符串等。它不应崩溃,例如因为选择了空列表的最后一个索引。然而,由于即使是我上面问题中难看的答案也需要不止一行代码来完成,我想一行代码可能不可能做到这一点(仅仅因为在处理之前需要检查re.search()
或{
这看起来不像python,因为它不是一个单行线,它使用
range(len(foo))
,但它非常简单,而且可能不会太低效。在其思想是从最短到最长迭代
string
的后缀,并检查它是否与pattern
匹配。在因为我们是从末尾检查的,所以我们确定我们遇到的第一个匹配模式的子字符串是最后一个。在
在我看来,你只需要最后一个与给定模式相匹配的位置(在本例中是非数字模式)。
这就像Python一样:
在
或者与函数完全相同,并且有更多的测试用例:
^{pr2}$您可以使用
re.finditer
来提取所有匹配项的起始位置,并从列表中返回最后一个。试试下面的Python代码:印刷品:
^{pr2}$编辑: 为了使解决方案更加优雅,以便在所有类型的输入中都能正常工作,下面是更新的代码。现在解决方案分为两行,因为必须执行检查如果list为空,那么它将打印-1,否则将打印索引值:
打印以下内容,如果没有找到这样的索引,则打印
None
而不是索引:编辑2: 正如OP在他的帖子中所说,
\d
只是我们开始的一个例子,因此我想出了一个解决方案来处理任何通用的regex。但是,如果这个问题真的只能用\d
来解决,那么我可以给出一个更好的解决方案,它根本不需要列表理解,而且可以通过使用更好的regex来查找最后一个出现的非数字字符并打印其位置来轻松编写。我们可以使用.*(\D)
regex查找最后出现的非数字,并使用以下Python代码轻松打印其索引:如果找不到任何非数字字符和
None
的字符串及其相应索引:正如您所看到的,这段代码不需要使用任何列表理解,而且更好,因为它只需通过一个regex调用
match
来查找索引。在但如果OP确实意味着要使用任何通用regex模式编写它,那么需要使用comprehension编写上面的代码。我甚至可以把它写成一个函数,它可以把正则表达式(比如
\d
或者甚至是复杂的)作为参数,并动态地生成一个传递的正则表达式的负数并在代码中使用它。如果真的需要,请告诉我。在相关问题 更多 >
编程相关推荐