删除字符串中的多个子字符串

时间:2015-06-30 21:32:53

标签: python regex

这里希望有人可以对这个问题有所了解,因为它让我难过。我有一个看起来像这样的字符串:

s = "abcdef [[xxxx xxx|ghijk]] lmnop [[qrs]] tuv [[xx xxxx|wxyz]] 0123456789"

我想要这个结果:

abcdef ghijk lmnop qrs tuv wxyz 0123456789

在这里回顾了很多问题和答案后,我最接近解决方案的是:

s = "abcdef [[xxxx xxx|ghijk]] lmnop [[qrs]] tuv [[xx xxxx|wxyz]] 0123456789"
s = re.sub('\[\[.*?\|', '', s)
s = re.sub('[\]\]]', '', s)
--> abcdef ghijk lmnop wxyz 0123456789

由于并非双括号内的每个子字符串都包含一个管道,因此re.sub会删除“[[”到下一个'|'的所有内容而不是在每组双括号内检查。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

这个怎么样:

In [187]: re.sub(r'([\[|\]])|((?<=\[)\w+\s+\w+(?=|))', '', s)
Out[187]: 'abcdef ghijk lmnop qrs tuv wxyz 0123456789'

答案 1 :(得分:1)

我给你一个相反的方法,而不是删除它你可以只捕捉你想要的模式。我认为这种方式可以使你的代码更具语义性。

您希望捕获两种模式:

  1. 案例:[[...]]以外的字词

    模式:任何单词都由']] '引导或由' [['尾随。

    正则表达式:(?<=\]\]\s)\w+|\w+(?=\s\[\[)

  2. 案例:[[...]]

    中的字词

    模式:']]'

    跟踪任何单词

    正则表达式:\w+(?=\]\])

  3. 示例代码

    1 #!/usr/bin/env python
    2 import re
    3
    4 s = "abcdef [[xxxx xxx|ghijk]] lmnop [[qrs]] tuv [[xx xxxx|wxyz]] 0123456789    "
    5
    6 p = re.compile('(?<=\]\]\s)\w+|\w+(?=\s\[\[)|\w+(?=\]\])')
    7 print p.findall(s)
    

    结果:

    ['abcdef', 'ghijk', 'lmnop', 'qrs', 'tuv', 'wxyz', '0123456789']
    

答案 2 :(得分:0)

作为使用内置re模块的一般正则表达式,您可以使用使用look-around的后续正则表达式:

(?<!\[\[)\b([\w]+)\b(?!\|)|\[\[([^|]*)\]\]

您可以使用re.finditer来获得所需的结果:

>>> g=re.finditer(r'(?<!\[\[)\b([\w]+)\b(?!\|)|(?<=\[\[)[^|]*(?=\]\])',s)
>>> [j.group() for j in g]
['abcdef', 'ghijk', 'lmnop', 'qrs', 'tuv', 'wxyz', '0123456789']

前面的正则表达式包含2个第一部分:

(?<=\[\[)[^|]*(?=\]\])

匹配|后面没有[[后面的任何单词字符组合,而不是\[\[([^|]*)\]\] 之前。

第二部分是:

|

将匹配除public function add() { $multimedia = $this->Multimedia->newEntity(); if ($this->request->is('post')) { $multimedia = $this->Multimedia->patchEntity($multimedia, $this->request->data); $file = $_FILES['url']; $path = 'files/' .$_FILES['url']['name']; move_uploaded_file($this->data['url']['tmp_name'], $path); if ($this->Multimedia->save($multimedia)) { $this->Flash->success('The multimedia has been saved.'); return $this->redirect(['action' => 'index']); } else { $this->Flash->error('The multimedia could not be saved. Please, try again.'); } } $categories = $this->Multimedia->Categories->find('list', ['limit' => 200]); $this->set(compact('multimedia', 'categories')); $this->set('_serialize', ['multimedia']); } 之外的两个括号之间的任何内容。

答案 3 :(得分:0)

>>> import re
>>> s = "abcdef [[xxxx xxx|ghijk]] lmnop [[qrs]] tuv [[xx xxxx|wxyz]] 0123456789"
>>> re.sub(r'(\[\[[^]]+?\|)|([\[\]])', '', s)
'abcdef ghijk lmnop qrs tuv wxyz 0123456789'

这将搜索并删除以下两项:

  1. 两个开口括号后面跟着一堆东西,这些东西不是一个封闭的支架,后面是一根管子。
  2. 打开或关闭括号。