【问题标题】:Python: Split a string by a word which contains a substringPython:用包含子字符串的单词拆分字符串
【发布时间】:2023-04-03 13:27:08
【问题描述】:

我有一个字符串text = "Fix me a meeting in 2 days"。 我有一些单词列表meetingStrings"meet"meetingStrings 中。所以,我必须通过会议来拆分文本。

期望的输出:

两天后

meetingStrings = [
    "appointment",
    "meet",
    "interview"
]
text = "Fix me a meeting in 2 days"
for x in meetingStrings:
    if x in text.lower(): 
        txt = text.split(x, 1)[1]
        print(txt)

这给出了输出:

两天后。

【问题讨论】:

    标签: python regex python-3.x string split


    【解决方案1】:

    使用re.split()

    import re
    
    meetingStrings = [
        "appointment",
        "meet",
        "interview"
    ]
    
    text = "Fix me a meeting in 2 days"
    
    print(re.split('|'.join(r'(?:\b\w*'+re.escape(w)+r'\w*\b)' for w in meetingStrings), text, 1)[-1])
    

    打印:

     in 2 days
    

    【讨论】:

    • 嗨@Andrej 感谢您的回答,但我想要的输出是“2 天内”
    • 问题不太清楚,但我怀疑所需的输出是['Fix me a', 'in 2 days']
    【解决方案2】:

    对您的代码稍作改动:

    meetingStrings = [
        "appointment",
        "meet",
        "interview"
    ]
    text = "Fix me a meeting in 2 days"
    for x in meetingStrings:
        if x in text.lower():
            txt = text.split(x, 1)[1]
            print(txt.split(" ", 1)[1]) #<--- Here
    

    只需获取最终输出,并在第一次出现空格时拆分

    【讨论】:

      【解决方案3】:

      此表达式也可能与 i 标志一起使用:

      (?:meet|interview|appointment)\S*\s+((?:in|after)\s[0-9]+\s+(?:days?|months?|weeks?|years?))
      

      我们可以使用逻辑 OR 在非捕获组中包含我们可能想要的任何所需单词,例如:

      (?:in|after|on|from)
      

      (?:days?|months?|weeks?|years?|hours?)
      

      (?:meet|interview|appointment|session|schedule)
      

      测试

      import re
      
      regex = r"(?:meet|interview|appointment)\S*\s+((?:in|after)\s[0-9]+\s+(?:days?|months?|weeks?|years?))"
      test_str = "Fix me a meeting in 2 days meetings in 2 months meet in 1 week nomeeting in 2 days meet after 2 days"
      
      print(re.findall(regex, test_str, re.IGNORECASE))
      

      输出

      ['in 2 days', 'in 2 months', 'in 1 week', 'in 2 days', 'after 2 days']
      

      如果您想探索/简化/修改它,this demo 的右上方面板上会解释该表达式。

      正则表达式电路

      jex.im 可视化正则表达式:

      【讨论】:

      • 但这不包括 meetingStrings 替代品
      【解决方案4】:

      试试这个:

      import re
      text = "Fix me a meeting in 2 days"
      print(re.split("({})\\w*".format("|".join(meetingStrings)), text)[-1].strip())
      

      输出:in 2 days

      【讨论】:

        【解决方案5】:

        没有正则表达式,str.partition-ing:

        for x in meetingStrings: 
            pre, _, post = text.lower().partition(x) 
            if post: 
                pre = pre.rpartition(' ')[0] if not pre.endswith(' ') else pre.rstrip() 
                post = post.partition(' ')[-1] if not post.startswith(' ') else post.lstrip() 
                print([pre, post]) 
        

        示例:

        In [35]: meetingStrings = [ 
            ...:     "appointment", 
            ...:     "meet", 
            ...:     "interview" 
            ...: ] 
            ...: text = "Fix me a meeting in 2 days" 
        
            ...: for x in meetingStrings: 
            ...:     pre, _, post = text.lower().partition(x) 
            ...:     if post: 
            ...:         pre = pre.rpartition(' ')[0] if not pre.endswith(' ') else pre.rstrip() 
            ...:         post = post.partition(' ')[-1] if not post.startswith(' ') else post.lstrip() 
            ...:         print([pre, post]) 
            ...:                                                                                                                                                                                                    
        ['fix me a', 'in 2 days']
        

        【讨论】:

          【解决方案6】:

          试试这样的:

          import re
          
          meetingStrings = [
                  "appointment",
                  "meet",
                  "interview"
          ]
          text = "Fix me a meeting in 2 days"
          
          def split_string(text, strings):
              search = re.compile('|'.join(strings))
              start = None
              input = text.split()
              for e, x in enumerate(input):
                  if search.search(x):
                      if start < e:
                          yield ' '.join(input[start:e])
                      start = None
                  else:
                      if start is None:
                          start = e
              else:
                  if start is not None:
                      yield ' '.join(input[start:])
          
          print(' '.join(split_string(text, meetingStrings)))
          

          这可能比其他答案更长,但似乎正是你想要的 - 拆分字符串,其中包含作为子字符串传入的字符串之一。

          【讨论】:

            【解决方案7】:

            你可以只使用 find() 和 list slice:

            text = "Fix me a meeting in 2 days"
            meetingStrings = [
                "appointment",
                "meet",
                "interview"
            ]
            
            
            sep = [i for i in meetingStrings if i in text]
            
            idx = text.find(sep[0])
            idx_ = text[idx:].find(' ')
            print (text[idx+idx_:])
            

            输出:

            in 2 days
            

            【讨论】:

              【解决方案8】:

              我有另一种更简单的方法,首先拆分句子中的所有单词,然后从出现meetingStrings 的位置删除句子:

              l=text.split()
              for i in meetingStrings:
                  for idx, j in enumerate(l):
                      if i in j:
                          l=l[idx+1:] 
              print(' '.join(l))
              

              给予:

              'in 2 days'
              

              【讨论】:

                【解决方案9】:

                这是为了使用搜索。
                您需要做的就是将文本放在单词的中间
                然后匹配单词。

                结果在捕获组 1 中。

                没有空格修剪

                \b\w*(?:appointment|meet|interview)\w*\b(.*)

                https://regex101.com/r/lK4zRz/1

                可读版本

                 \b 
                 \w* 
                 (?:
                      appointment
                   |  meet
                   |  interview
                 )
                 \w* 
                 \b 
                 ( .* )                        # (1)
                

                带空格修剪

                (?m)\b\w*(?:appointment|meet|interview)\w*\b[^\S\r\n]*(.*?)[^\S\r\n]*$

                https://regex101.com/r/v2qAOQ/1


                此外,如果您在任一正则表达式的开头添加 .*
                它总是会得到最后一个关键字。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-05-20
                  • 2010-12-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多