python 正则表达式匹配并替换字符串的开头和结尾但保留中间
Posted
技术标签:
【中文标题】python 正则表达式匹配并替换字符串的开头和结尾但保留中间【英文标题】:python regex match and replace beginning and end of string but keep the middle 【发布时间】:2017-12-31 16:35:10 【问题描述】:我有一个带有假日名称的数据框。我有一个问题,在某些日子里,假期在不同的日子,有时在另一个假期的那天。以下是一些示例问题:
1 "Independence Day (Observed)"
2 "Christmas Eve, Christmas Day (Observed)"
3 "New Year's Eve, New Year's Day (Observed)"
4 "Martin Luther King, Jr. Day"
我想用 '' 替换所有 ' (Observed)' 和逗号之前的所有内容,前提是匹配 ' (Observed)'。输出应该是:
1 "Independence Day"
2 "Christmas Day"
3 "New Year's Day"
4 "Martin Luther King, Jr. Day"
我能够独立完成这两件事:
(foo['holiday']
.replace(to_replace=' \(Observed\)', value='', regex=True)
.replace(to_replace='.+, ', value='', regex=True))
但这导致了“小马丁路德金”的问题。
【问题讨论】:
(Observed)
总是在字符串的末尾吗?
是的。从克里斯那里得到了答案
【参考方案1】:
替换.py
>import re
input = [
"Independence Day (Observed)",
"Christmas Eve, Christmas Day (Observed)",
"New Year's Eve, New Year's Day (Observed)",
"Martin Luther King, Jr. Day"
]
for holiday in input:
print re.sub('^(.*?, )?(.*?)( \(Observed\))$', '\\2', holiday)
输出
> python replace.py
Independence Day
Christmas Day
New Year's Day
Martin Luther King, Jr. Day
说明
^
:匹配字符串开头。
(.*?, )?
:匹配任何后跟命令和空格的内容。使其成为惰性匹配,因此它不会消耗我们想要保留的字符串部分。最后一个 ?
使整个事情成为可选的,因为某些示例输入根本没有逗号。
(.*?)
:抓取我们想要的部分,以备以后在捕获组中使用。这部分也是懒惰的匹配,因为...
( \(Observed\))
:某些字符串的末尾可能有“(已观察)”,因此我们在此处将其声明在单独的组中。前一段中的惰性匹配不会消耗这个。
$
: 在字符串末尾匹配。
【讨论】:
你说你有一个DataFrame
,但这会导致 Python list
而不是和 Pandas DataFrame
保持一致。这样会丢失索引和名称。
谢谢!作为参考,这是我将替换应用于我的数据框列的最终代码:foo['holiday'].replace(to_replace='^(.*?, )?(.*?)( \(Observed\))$', value=r'\2', regex=True)
【参考方案2】:
我建议
r'^(?:.*,\s*)?\b([^,]+)\s+\(Observed\).*'
替换为r'\1'
反向引用。
请参阅regex demo。
模式详情:
^
- 字符串开头
(?:.*,\s*)?
- 可选序列:
.*,
- 尽可能多的除换行符以外的任何 0+ 字符,直到最后一次出现 ,
,然后是 ,
\s*
- 0 个或多个空格
\b
- 单词边界
([^,]+)
- 除,
之外的 1 个或多个字符
\s+
- 1 个或多个空格
\(Observed\)
- 文字子字符串 (Observed)
.*
- 除了换行符之外的任何 0+ 字符,尽可能多到行尾。
【讨论】:
以上是关于python 正则表达式匹配并替换字符串的开头和结尾但保留中间的主要内容,如果未能解决你的问题,请参考以下文章