简体   繁体   English

将两个字符串与一个公共子字符串连接在一起?

[英]Concatenate two strings with a common substring?

Say I have strings, 说我有琴弦

string1 = 'Hello how are you'
string2 = 'are you doing now?'

The result should be something like 结果应该是这样的

Hello how are you doing now?

I was thinking different ways using re and string search. 我在考虑使用re和字符串搜索的不同方式。 ( Longest common substring problem ) 最长的普通子串问题

But is there any simple way (or library) that does this in python? 但是有没有简单的方法(或库)在python中做到这一点?

To make things clear i'll add one more set of test strings! 为了清楚起见,我将再添加一组测试字符串!

string1 = 'This is a nice ACADEMY'
string2 = 'DEMY you know!'

the result would be!, 结果就是!,

'This is a nice ACADEMY you know!'

This should do: 应该这样做:

string1 = 'Hello how are you'
string2 = 'are you doing now?'
i = 0
while not string2.startswith(string1[i:]):
    i += 1

sFinal = string1[:i] + string2

OUTPUT : 输出:

>>> sFinal
'Hello how are you doing now?'

or, make it a function so that you can use it again without rewriting: 或者,使其成为一个函数,以便您无需重写即可再次使用它:

def merge(s1, s2):
    i = 0
    while not s2.startswith(s1[i:]):
        i += 1
    return s1[:i] + s2

OUTPUT : 输出:

>>> merge('Hello how are you', 'are you doing now?')
'Hello how are you doing now?'
>>> merge("This is a nice ACADEMY", "DEMY you know!")
'This is a nice ACADEMY you know!'

This should do what you want: 这应该做您想要的:

def overlap_concat(s1, s2):
    l = min(len(s1), len(s2))
    for i in range(l, 0, -1):
        if s1.endswith(s2[:i]):
            return s1 + s2[i:]
    return s1 + s2

Examples: 例子:

>>> overlap_concat("Hello how are you", "are you doing now?")
'Hello how are you doing now?'
>>> 

>>> overlap_concat("This is a nice ACADEMY", "DEMY you know!")
'This is a nice ACADEMY you know!'
>>> 

Using str.endswith and enumerate : 使用str.endswithenumerate

def overlap(string1, string2):
    for i, s in enumerate(string2, 1):
         if string1.endswith(string2[:i]):
            break

    return string1 + string2[i:]
>>> overlap("Hello how are you", "are you doing now?")
'Hello how are you doing now?'

>>> overlap("This is a nice ACADEMY", "DEMY you know!")
'This is a nice ACADEMY you know!'

If you were to account for trailing special characters, you'd be wanting to employ some re based substitution. 如果要考虑尾随特殊字符,则需要使用一些基于re的替换。

import re
string1 = re.sub('[^\w\s]', '', string1)

Although note that this would remove all special characters in the first string. 尽管注意,这会删除第一个字符串中的所有特殊字符。


A modification to the above function which will find the longest matching substring (instead of the shortest) involves traversing string2 in reverse. 对上述函数的修改将找到最长的匹配子字符串(而不是最短的子字符串),涉及反向遍历string2

def overlap(string1, string2):
   for i in range(len(s)):
      if string1.endswith(string2[:len(string2) - i]):
          break

   return string1 + string2[len(string2) - i:]
>>> overlap('Where did', 'did you go?') 
'Where did you go?'

Other answers were great guys but it did fail for this input. 其他答案都是好人,但对于此输入确实失败了。

string1 = 'THE ACADEMY has'
string2= '.CADEMY has taken'

output: 输出:

>>> merge(string1,string2)
'THE ACADEMY has.CADEMY has taken'
>>> overlap(string1,string2)
'THE ACADEMY has'

However there's this standard library difflib which proved to be effective in my case! 但是,有一个标准库difflib在我的情况下被证明是有效的!

match = SequenceMatcher(None, string1,\
                        string2).find_longest_match\
                        (0, len(string1), 0, len(string2))

print(match)  # -> Match(a=0, b=15, size=9)
print(string1[: match.a + match.size]+string2[match.b + match.size:]) 

output: 输出:

Match(a=5, b=1, size=10)
THE ACADEMY has taken

which words you want to replace are appearing in the second string so you can try something like : 您要替换的单词出现在第二个字符串中,因此您可以尝试以下操作:

new_string=[string2.split()]
new=[]
new1=[j for item in new_string for j in item if j not in string1]
new1.insert(0,string1)
print(" ".join(new1))

with the first test case: 与第一个测试用例:

string1 = 'Hello how are you'
string2 = 'are you doing now?'

output: 输出:

Hello how are you doing now?

second test case: 第二个测试用例:

string1 = 'This is a nice ACADEMY'
string2 = 'DEMY you know!'

output: 输出:

This is a nice ACADEMY you know!

Explanation : 说明:

first, we are splitting the second string so we can find which words we have to remove or replace : 首先,我们将第二个字符串拆分,以便可以找到必须删除或替换的单词:

new_string=[string2.split()]

second step we will check each word of this splitter string with string1 , if any word is in that string than choose only first string word , leave that word in second string : 第二步,我们将使用string1检查此分隔符字符串的每个单词,如果该字符串中有任何单词而不是仅选择第一个字符串单词,则将该单词保留在第二个字符串中:

new1=[j for item in new_string for j in item if j not in string1]

This list comprehension is same as : 此列表理解与:

new1=[]
for item in new_string:
    for j in item:
        if j not in string1:
            new1.append(j)

last step combines both string and join the list: 最后一步结合了字符串和连接列表:

new1.insert(0,string1)
print(" ".join(new1))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM