繁体   English   中英

从大字符串中提取子字符串

[英]extract substring from large string

我有一个字符串:

string="(2021-07-02 01:00:00 AM BST)  
---  
syl.hs has joined the conversation  
  
  

(2021-07-02 01:00:23 AM BST)  
---  
e.wang  
Good Morning
How're you?
  
  
  

(2021-07-02 01:05:11 AM BST)  
---  
wk.wang  
Hi, I'm Good.  
  
  

(2021-07-02 01:08:01 AM BST)  
---  
perter.derrek   
we got the update on work. 
It will get complete by next week.

(2021-07-15 08:59:41 PM BST)  
---  
ad.ft has left the conversation  
  
  
  
  
---  
  
* * *"

我只想提取对话文本(名称和时间戳之间的文本)预期输出为:

评论=['早安,你好吗?','嗨,我很好。','我们收到了工作更新。下周将完成。']

我尝试过的是:

评论=re.findall(r'---\\s*\\n(. (?:\\n(?!(?:(\\s \\d{4}-\\d{2}-\\d{2}\\ s\\d{2}:\\d{2}:\\d{2}\\s*[AP]M\\s+GMT\\s*)\\w+\\s*\\n)?---). ) )' ,细绳)

您可以使用单个捕获组:

^---\s*\n(?!.* has (?:joined|left) the conversation|\* \* \*)\S.*((?:\n(?!\(\d|---).*)*)

模式匹配:

  • ^字符串开始
  • ---\\s*\\n匹配---可选的空白字符和换行符
  • (?!.* has (?:joined|left) the conversation|\\* \\* \\*)断言该行不包含has joinedhas left会话部分,或包含* * *
  • \\S.*在行首和行的其余部分至少匹配一个非空白字符
  • (捕获组 1 (这将由 re.findall 返回)
    • (?:\\n(?!\\(\\d|---).*)*匹配所有不以(和数字或 -- 开头的行
  • )关闭第 1 组

请参阅正则表达式演示Python 演示

例子

pattern = r"^---\s*\n(?!.* has (?:joined|left) the conversation|\* \* \*)\S.*((?:\n(?!\(\d|---).*)*)"
result = [m.strip() for m in re.findall(pattern, s, re.M) if m]
print(result)

输出

["Good Morning\nHow're you?", "Hi, I'm Good.", 'we got the update on work. \nIt will get complete by next week.']

我假设:

  • 感兴趣的文本在三行之后开始:一行包含时间戳,然后是行"---" ,可以用空格填充右侧,然后是由包含一个的字符串组成的行句点既不在该字符串的开头也不在该字符串的结尾,并且该字符串的右侧可以用空格填充。
  • 感兴趣的文本块可能包含空行,空行是只包含空格和行终止符的字符串。
  • 感兴趣的文本块的最后一行不能是空行。

我相信以下正则表达式(设置了多行 ( m ) 和大小写无关 ( i ) 标志)满足这些要求。

^\(\d{4}\-\d{2}\-\d{2} .*\) *\r?\n-{3} *\r?\n[a-z]+\.[a-z]+ *\r?\n((?:.*[^ (\n].*\r?\n| *\r?\n(?=(?: *\r?\n)*(?!\(\d{4}\-\d{2}\-\d{2} .*\)).*[^ (\n]))*)

感兴趣的线块包含在捕获组 1 中。

启动你的引擎!

表达式的元素如下。

^\(\d{4}\-\d{2}\-\d{2} .*\) *\r?\n  # match timestamp line
-{3} *\r?\n                         # match 3-hyphen line
[a-z]+\.[a-z]+ *\r?\n               # match name
(                                   # begin capture group 1
  (?:                               # begin non-capture group (a)
    .*[^ (\n].*\r?\n                # match a non-blank line
    |                               # or
    \ *\r?\n                        # match a blank line
    (?=                             # begin a positive lookahead
      (?:                           # begin non-capture group (b)
        \ *\r?\n                    # match a blank line
      )*                            # end non-capture group b and execute 0+ times
      (?!                           # begin a negative lookahead
        \(\d{4}\-\d{2}\-\d{2} .*\)  # match timestamp line
      )                             # end negative lookahead
      .*[^ (\n]                     # march a non-blank line
    )                               # end positive lookahead
  )*                                # end non-capture group a and execute 0+ times
)                                   # end capture group 1

这是一个自我记录的正则表达式,它将去除前导和尾随空格:

(?x)(?m)(?s)                                                    # re.X, re.M, re.S (DOTALL)
(?:                                                             # start of non capturing group
 ^\(\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}\ [AP]M\ BST\)\s*\r?\n  # date and time
 (?!---\s*\r?\nad\.ft has)                                      # next lines are not the ---\n\ad.ft etc.
 ---\s*\r?\n                                                    # --- line
 [\w.]+\s*\r?\n                                                 # name line
 \s*                                                            # skip leading whitespace
)                                                               # end of non-capture group
# The folowing is capture group 1. Match characters until you get to the next date-time:
((?:(?!\s*\r?\n\(\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}\ [AP]M\ BST\)).)*)# skip trailing whitespace

请参阅正则表达式演示

见 Python 演示

import re

string = """(2021-07-02 01:00:00 AM BST)
---
syl.hs has joined the conversation



(2021-07-02 01:00:23 AM BST)
---
e.wang
Good Morning
How're you?




(2021-07-02 01:05:11 AM BST)
---
wk.wang
Hi, I'm Good.



(2021-07-02 01:08:01 AM BST)
---
perter.derrek
we got the update on work.
It will get complete by next week.

(2021-07-15 08:59:41 PM BST)
---
ad.ft has left the conversation




---

* * *"""

regex = r'''(?x)(?m)(?s)                                        # re.X, re.M, re.S (DOTALL)
(?:                                                             # start of non capturing group
 ^\(\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}\ [AP]M\ BST\)\s*\r?\n  # date and time
 (?!---\s*\r?\nad\.ft has)                                      # next lines are not the ---\n\ad.ft etc.
 ---\s*\r?\n                                                    # --- line
 [\w.]+\s*\r?\n                                                 # name line
 \s*                                                            # skip leading whitespace
)                                                               # end of non-capture group
# The folowing is capture group 1. Match characters until you get to the next date-time:
((?:(?!\s*\r?\n\(\d{4}-\d{2}-\d{2}\ \d{2}:\d{2}:\d{2}\ [AP]M\ BST\)).)*)# skip trailing whitespace
'''

matches = re.findall(regex, string)
print(matches)

印刷:

["Good Morning\nHow're you?", "Hi, I'm Good.", 'we got the update on work.\nIt will get complete by next week.']

暂无
暂无

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

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