使用正则表达式从字符串中提取文本

时间:2018-08-17 10:51:34

标签: python regex

我的弦很大。该字符串中有很多段落。每个段落均以标题开头,并遵循特定模式。

示例:

== Title1 == // Paragraph starts ............. ............. // Some texts ............. End of Paragraph ===Title2 === // Paragraph starts ............. ............. // Some texts .............

标题的样式为:

  

1。)新段落 title 以等于(=)开头,后可以跟任意数量的=。

     

2。)=之后,可以有一个空格(虽然不是必需的),然后是文本。

     

3。)文本完成后,可以再次有一个空格(不是必需的),然后再跟任意数量的等于(=)。

     

4。)现在开始该段落。我必须提取文本,直到遇到类似的模式。

有人可以通过正则表达式帮助我吗? TIA

4 个答案:

答案 0 :(得分:3)

您可以使用

re.findall(r'(?m)^=+[^\S\r\n]*(.*?)[^\S\r\n]*=+\s*(.*(?:\r?\n(?!=+.*?=).*)*)', s)

请参见regex demo

详细信息

  • (?m)^-一行的开头
  • =+-1个或更多=字符
  • [^\S\r\n]*-零个或多个CR和LF以外的空白字符
  • (.*?)-第1组:除换行符外,任何零个或多个字符,并且尽可能少
  • [^\S\r\n]*-零个或多个CR和LF以外的空白字符
  • =+-1个或更多=字符
  • \s*-超过0个空格
  • (.*(?:\r?\n(?!==+.*?=).*)*)-第2组:
    • .*-尽可能多的零个或多个字符(除换行符以外)
    • (?:\r?\n(?!=+.*?=).*)*-零个或多个序列
      • \r?\n(?!=+.*?=)-一个可选的CR,然后是LF,后跟1+ =,然后是除换行符以外的任何其他字符,并尽可能少,然后再加上1+ {{1} } s
      • =-尽可能多的零个或多个字符(除换行符以外)

Python demo

.*

输出:

import re

rx = r"(?m)^=+[^\S\r\n]*(.*?)[^\S\r\n]*=+\s*(.*(?:\r?\n(?!=+.*?=).*)*)"
s = "== Title1 ==\n..........................\n.............\nEnd of Paragraph\n===Title2 ===\n.............\n.............\n............."
print(re.findall(rx, s))

答案 1 :(得分:2)

您可以尝试-

x = "== Title1   ==="
ptrn = "[=]{1,}[\s]{0,}[\w]+[\s]{0,}[=]{1,}"
if re.search(ptrn, x):
    x = x.replace('=', '').strip()

将给您Title1。或者假设您希望列表中所有匹配的标题,都可以-

x = '== Title1   ===nansnsk fnasasklsanlkas lkaslkans \n== Title2 ==='
titles = [i.replace('=', '').strip() for i in re.findall(ptrn, x)]
# OP ['Title1', 'Title2']

模式是-

"^[=]{1,}[\s]{0,}[\w]+[\s]{0,}[=]{1,}"
  

^ [=] {1,}-开头至少匹配一个等号

     

[\ s] {0,}-零到无限等号之间的匹配

     

[\ w] +-一次或多次匹配[a-zA-Z0-9 _]

之后,我们可以通过将=替换为''并将其去除空格来从中提取文本。您可以在regex101尝试一下,这对于测试正则表达式确实很有帮助

答案 2 :(得分:2)

这可能有助于查找每个段落的标题和每个段落的行。

text = """== Title1 == // Paragraph starts
.............
............. // Some texts
.............
End of Paragraph
===Title2 === // Paragraph starts
.............
............. // Some texts
.............
"""
import re

reg = re.compile(r'(?:[=]+\s*\w+\s*[=]+)')

for i in text.split('\n'):
    if re.search(reg, i):
        t = re.sub(r'=', '', i)
        print('Title:', t.strip())
    else:
        print('line:', i.strip())

 # Output like this
   Title: Title1  // Paragraph starts
   line: .............
   line: ............. // Some texts
   line: .............
   line: End of Paragraph
   Title: Title2  // Paragraph starts
   line: .............
   line: ............. // Some texts
   line: .............
   line: 

答案 3 :(得分:1)

  

1。)新段落标题以等于(=)开头,后可以跟任意数量的=。

这可以用=+表示。

  

2。)=之后,可以有一个空格(虽然不是必需的),然后是文本。

     

3。)文本完成后,可以再次有一个空格(不是必需的),然后再跟任意数量的等于(=)。

因此标题的模式变为:=+[^=]+=+\n,表示匹配至少一个=,然后匹配不包括=的一些文本,然后再匹配至少一个{{1} }。

在这些模式之间捕获所有内容将为您提供所需的文本。

在以下模式中,整个匹配项包括标题,第一组包含文本。

最后,您的模式将是:=

Demo