Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:匹配字符串中的多个子字符串_Python_Regex_Python 3.x_String_Substring - Fatal编程技术网

Python:匹配字符串中的多个子字符串

Python:匹配字符串中的多个子字符串,python,regex,python-3.x,string,substring,Python,Regex,Python 3.x,String,Substring,我正在使用Python,希望将给定字符串与多个子字符串匹配。我试图用两种不同的方法来解决这个问题。我的第一个解决方案是将子字符串与字符串匹配,如下所示: str = "This is a test string from which I want to match multiple substrings" value = ["test", "match", "multiple", "ring"] temp = [] temp.extend([x.upper() for x in value if

我正在使用Python,希望将给定字符串与多个子字符串匹配。我试图用两种不同的方法来解决这个问题。我的第一个解决方案是将子字符串与字符串匹配,如下所示:

str = "This is a test string from which I want to match multiple substrings"
value = ["test", "match", "multiple", "ring"]
temp = []
temp.extend([x.upper() for x in value if x.lower() in str.lower()])
print(temp)
这将导致temp=[“测试”、“匹配”、“多个”、“环”]

然而,这不是我想要的结果。子字符串应该完全匹配,因此“环”不应该与“字符串”匹配

这就是我试图用正则表达式解决这个问题的原因,如下所示:

str = "This is a test string from which I want to match multiple substrings"
value = ["test", "match", "multiple", "ring"]
temp = []
temp.extend([x.upper() for x in value if regex.search(r"\b" + regex.escape(x) + r"\b", str,
                                                   regex.IGNORECASE) is not None])
print(temp)
str = ['Hi,', 'how', 'are', 'you?']`
values = ['how', 'you', 'time', 'space']

new_str = []
for word in str:
  for j in values:
    if word.startswith(j):
      new_str.append(word)

# result -> ['how', 'you?']
结果是[“测试”、“匹配”、“多个”],这是正确的解决方案。尽管如此,这个解决方案的计算时间太长。我必须对大约100万个字符串进行检查,使用regex的解决方案需要几天才能完成,而使用第一个解决方案需要1.5个小时

我想知道是否有办法让第一个解决方案工作,或者让第二个解决方案运行得更快。提前谢谢


编辑:
value
也可以包含数字,或者像“test1 test2”这样的短短语

您可以按空格拆分
str
,然后将
value
中的元素与
=
匹配

编辑:


所以你说
值中的一些字符串可以在它们之前或之后有空格。您可以通过以下行解决此问题:

values = [i.strip() for i in values]
这将删除字符串前后的所有空白字符(对于每个元素)

此外,您还提到,如果您将
str
按空格拆分,一些单词会在拆分过程中留下标点符号-->
“你好吗?”
将导致
['Hi','how','are','you']
。您可以通过使用字符串
startswith()
内置方法从
值中筛选以元素开头的所有单词来解决此问题,如下所示:

str = "This is a test string from which I want to match multiple substrings"
value = ["test", "match", "multiple", "ring"]
temp = []
temp.extend([x.upper() for x in value if regex.search(r"\b" + regex.escape(x) + r"\b", str,
                                                   regex.IGNORECASE) is not None])
print(temp)
str = ['Hi,', 'how', 'are', 'you?']`
values = ['how', 'you', 'time', 'space']

new_str = []
for word in str:
  for j in values:
    if word.startswith(j):
      new_str.append(word)

# result -> ['how', 'you?']
然后,您可以使用一些正则表达式从结果列表中删除标点符号,但现在您将有更小的列表可供迭代。删除所有标点符号后,就可以按照我在原始答案中的建议匹配整个字符串


我希望现在更清楚。

在没有看到实际数据的情况下,很难提出最佳解决方案,但您可以尝试以下方法:

  • 生成一个匹配所有值的模式。这样,您只需要搜索字符串一次(而不是每个值搜索一次)
  • 跳过转义值,除非它们包含特殊字符(如
    '^'
    '*'
  • 将结果直接分配给
    temp
    ,避免使用
    temp.extend()
    进行不必要的复制

我想到了两种可能的优化:

  • 使用
    re.compile
    预编译模式,这样它就不会在每次调用
    match
    时重新编译
  • 与其与四个独立的正则表达式匹配,不如创建一个与所有值匹配的正则表达式

结果:

['TEST', 'MATCH', 'TEST1 TEST2', 'MULTIPLE']
这种方法的潜在缺点:

  • 输出的顺序可能不同。您最初的方法将结果按其在
    值中出现的顺序排列。这种方法将结果按其在
    str
    中的显示顺序排列
  • 如果相同的值在
    str
    中多次出现,则该值将在
    temp
    中多次出现。与原始方法相反,该方法中的值最多在
    temp
    中出现一次
  • 搜索
    一旦找到匹配项就会终止
    findall
    始终搜索整个字符串。如果您希望大多数字符串与
    值中的每个单词匹配,并且希望大多数匹配项出现在字符串的早期,则
    findall
    可能比
    搜索
    慢。另一方面,如果您希望搜索经常出现
    None
    ,那么
    findall
    可能会更快一些
通过编译您的解决方案并在您的计算机上运行编译后的版本,您可能可以节省大量时间strings@jeremycg“编译您的解决方案”的确切含义是什么?
但当值包含诸如“test1 test2”之类的子字符串时,这不起作用。因此,如果value有一个单词包含在
str
中,那么应该有一个匹配?使用@Kevin在他的回答中提到的
re.compile
,如果
value
的元素包含空格,或者如果句子包含一个本来应该匹配的单词旁边的标点符号,那么你就可以做
value=[i.strip()表示i in值]
并使用字符串方法
startswith()从
str
中筛选项目
然后从筛选列表中删除标点符号并查看结果。对不起,我不确定我是否理解。您能否在答案中编辑一些完整的代码并演示其工作原理?谢谢您的编辑,但我认为我仍然缺少一些内容。当我运行该代码块时,我得到了
名称错误:名称“I”未定义
。“所以你说值中的某些字符串可以在它们之前或之后有空格。”我不认为他是这么说的。我认为他是说值中可以有空格,不一定在开头或结尾。例如,test1 test2包含空格。删除它是错误的,因为“test1 test2”不应匹配,将其拆分为多个元素是错误的,因为“test1”不应匹配,除非它紧跟在“test2”后面的空格之前.“编译”模式在这里不会带来任何好处,因为您只使用了一次。即使多次使用,也很可能忽略不计。我对实际问题的解释是,必须搜索数百万个字符串,而不仅仅是示例代码中的字符串。假设有一个
f或者以百万字符串表示的str:
紧跟在my
temp=[]
之后的一行。感谢您的回答,但这是您的第一个选择