【问题标题】:Regex joining words splitted by whitespace and hyphen正则表达式连接由空格和连字符分隔的单词
【发布时间】:2019-06-21 14:00:14
【问题描述】:

我的字符串很乱,看起来像这样:

s="I'm hope-less and can -not solve this pro- blem on my own. Wo - uld you help me?"

我希望将连字符(有时是空格)剥离的单词放在一个列表中。期望的输出:

list = ['I'm','hopeless','and','cannot','solve','this','problem','on','my','own','.','Would','you','help','me','?']

我尝试了很多不同的变体,但都没有奏效..

rgx = re.compile("([\w][\w'][\w\-]*\w)") s = "My string'" rgx.findall(s)

【问题讨论】:

  • 试试r"\w+(?:'\w+)?|[^\s\w]+"
  • 谢谢,但这只能部分解决我的问题。 “问题”
  • 啊,抱歉,我在手机上查看问题时错过了这一点。我认为您需要进行一些预处理,例如re.sub(r'\b\s*-\s*\b', '', s),但由于正则表达式不“了解”英语,并且这显然会删除单词字符之间的连字符,因此可能会删除太多。
  • s=s.replace('-', '').replace('-', '').replace('-', '').replace('-','' ).replace(' ', ',').split(',')

标签: python regex python-3.x whitespace hyphen


【解决方案1】:

这个怎么样:

>>> s
"I'm hope-less and can -not solve this pro- blem on my own. Wo - uld you help me
?"
>>> list(map(lambda x:re.sub(' *- *','',x), filter(lambda x:x, re.split(r'(?<!-) +(?!-)|([.?])',s))))
["I'm", 'hopeless', 'and', 'cannot', 'solve', 'this', 'problem', 'on', 'my', 'own', '.', 'Would', 'you', 'help', 'me', '?']

上面使用了简单的空格' ',但是使用\s更好:

list(map(lambda x:re.sub('\s*-\s*','',x), filter(lambda x:x, re.split(r'(?<!-)\s+(?!-)|([.?])',s))))

(?&lt;!-)\s+(?!-) 表示前后没有- 的空格。
[.?] 表示单个. 或?。

re.split(r'(?&lt;!-)\s+(?!-)|([.?])',s) 将相应地拆分字符串,但内部会有一些None 和空字符串'':

["I'm", None, 'hope-less', None, 'and', None, 'can -not', None, 'solve', None, 'this', None, 'pro- blem', None, 'on', None, 'my', None, 'own', '.', '', None, 'Wo - uld', None, 'you', None, 'help', None, 'me', '?', '']

此结果直接馈送到filter 以删除None 和'',然后馈送到map 以删除每个单词中的空格和-。

【讨论】:

    【解决方案2】:

    这是一种方法:

    [re.sub(r'\s*-\s*', '', i) for i in re.split(r'(?<!-)\s(?!-)', s)]
    
    # ["I'm", 'hopeless', 'and', 'cannot', 'solve', 'this', 'problem', 'on', 'my', 'own.', 'Would', 'you', 'help', 'me?']
    

    这里有两个操作:

    1. 使用否定的前瞻和否定的后瞻,基于空格不带连字符分割文本。

    2. 在每个拆分词中,将连字符前面或后面可能的空格替换为空字符串。

    你可以在这里看到第一个操作的演示:https://regex101.com/r/ayHPvY/2

    第二个:https://regex101.com/r/ayHPvY/1

    编辑:要同时分离 . 和 ?,请改用:

    [re.sub(r'\s*-\s*','', i) for i in re.split(r"(?<!-)\s(?!-)|([^\w\s'-]+)", s) if i]
    
    # ["I'm", 'hopeless', 'and', 'cannot', 'solve', 'this', 'problem', 'on', 'my', 'own', '.', 'Would', 'you', 'help', 'me', '?']
    

    问题还在于拆分非字母、非空格和连字符/撇号。 if i 是必需的,因为拆分可能会返回一些 None 项目。

    【讨论】:

    • 对于投反对票的人,希望在投反对票之前对这个答案进行批评。据我所知,我认为这种方法没有任何重大问题。
    • 出于某种原因,我看到很多关于正则表达式标签的反对意见,包括问题和答案......不知道为什么
    • 不是我反对,但我认为您的输出与 OP 的 Desired output 有点不同。
    • @Sundeep 可能是由于对正则表达式的大量滥用......很多问题都要求提供不需要它的正则表达式解决方案,或者提供的某些正则表达式解决方案优化得很差。我承认我自己不是正则表达式专家,这就是为什么我会感谢其他人指出问题并帮助我学习,而不是一票否决地走开。
    • @Tiw 好点,我没有注意到 . 和 ? 也被分开了。看到这被接受了,我会看看 OP 是否回来评论并相应地更新。
    【解决方案3】:

    快速、非正则表达式的方法是

    ''.join(map(lambda s: s.strip(), s.split('-'))).split()
    

    在连字符上分割,去除额外的空白,重新连接成字符串并在空格上分割,但这不会分隔点或问号。

    【讨论】:

      猜你喜欢
      • 2016-09-15
      • 1970-01-01
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多