python - 使用 re.sub 删除两个字符之间的空格
Posted
技术标签:
【中文标题】python - 使用 re.sub 删除两个字符之间的空格【英文标题】:python - remove whitespace between two characters using re.sub 【发布时间】:2021-05-02 16:49:37 【问题描述】:我有一对列,如下所示:
x = ["a b williams", "e g", "z z specialists"]
y = ["j j winston", "hb d party supplies", "t t ice cream"]
df = pd.DataFrame(x,y)
我希望能够使用re.sub
删除两个单个字符之间的空格。我尝试了以下方法:
re.sub("(?<=\\w\\b)"\\s"(?=\\w\\b)", "", df)
但是,当我运行代码时,出现以下错误。
SyntaxError: unexpected character after line continuation character
我不确定自己做错了什么。期望的结果是:
jj winston ab williams
hb d party supplies eg
tt ice cream zz specialists
请指教。任何建议表示赞赏。
【问题讨论】:
"(?<=\\w\\b)"\\s"(?=\\w\\b)"
语法无效。
那是df
的例子代表吗?您真的要在索引中替换吗?正则表达式相当简单,你可以使用r'(?<=\b[^\W\d_])\s(?=[^\W\d_]\b)'
。或者,如果您真的想将数字和下划线视为单词,r'(?<=\b\w)\s(?=\w\b)'
@WiktorStribiżew 我不确定你对索引的意思
我的意思是,df.replace(regex_here,'', regex=True)
不会在索引列中替换。好的,re.sub(r'(?<=\b[^\W\d_])\s(?=[^\W\d_]\b)','', text)
对你有用吗?请注意,您不能将df
作为输入参数传递给re.sub
,它必须是一个字符串。这就是为什么我要询问您数据的真实结构。
@TigerhawkT3 您不能将数据帧作为输入传递给re.sub
。
【参考方案1】:
你可以使用
(?<=\b[^\W\d_])\s(?=[^\W\d_]\b)
(?<=\b\w)\s(?=\w\b)
请参阅regex demo。请注意,[^\W\d_]
模式匹配 Python re
中的任何 Unicode 字母。 \w
匹配 Unicode 字母、数字、_
以及一些变音符号和其他连接符标点符号。
详情
(?<=\b[^\W\d_])
- 一个正向的后视,匹配一个紧跟在一个字母前面的位置作为一个完整的单词(因为它前面有一个单词边界)
\s
- 一个空格字符
(?=[^\W\d_]\b)
- 一个正向预测,它匹配一个紧跟一个字母作为整个单词的位置(因为它后面跟着一个单词边界)。
这是一个 Pandas 演示:
x = ["a b williams", "e g", "z z specialists"]
y = ["j j winston", "h d party supplies", "t t ice cream"]
df = pd.DataFrame(x,y)
rx = r'(?<=\b[^\W\d_])\s(?=[^\W\d_]\b)'
df.index = df.index.to_series().replace(rx, '', regex=True)
df = df.replace(rx, '', regex=True)
# => df
# 0
# jj winston ab williams
# hd party supplies eg
# tt ice cream zz specialists
由于DataFrame.replace
和regex=True
不涉及索引列,所以必须单独处理,因此增加了df.index = df.index.to_series().replace(rx, '', regex=True)
这行代码。
【讨论】:
你能解释一下单数模式\d_
是如何工作的吗?只是说只有一个空格吗?
@jvalenti \d_
在[^\W\d_]
否定字符类中表示digit
和_
,整体含义是任何字符,但非单词字符、数字和@ 987654339@。换句话说,除了数字和_
之外的任何单词字符。【参考方案2】:
您的正则表达式非常接近要求,可以稍作修改,如下所示:
r'(?<=\b\w)(\s)(?=\w\b)'
注意使用原始引号 r'...',这样您就不需要在正则表达式中使用双 \ for。
Regex Demo
更好地编译正则表达式以加快处理速度,因为它被多次使用
pattern = re.compile(r'(?<=\b\w)(\s)(?=\w\b)')
然后重复使用您的代码:
x = ["a b williams", "e g", "z z specialists"]
y = ["j j winston", "h d party supplies", "t t ice cream"]
df = pd.DataFrame(x,y)
转换索引:
df.index = df.index.to_series().str.replace(pattern, '')
转换数据列:
df[0] = df[0].str.replace(pattern, '')
你的错误解释:
-
你不能直接在整个 pandas DataFrame 上使用 re.sub
您的正则表达式包含 4 个引号“其中第二个”结束正则表达式,因此正则表达式的后续部分被 \ 标记视为续行,并且在续行之后被视为无效的字符
【讨论】:
【参考方案3】:使用re.sub
,我建议如下:
# your lists
x = ["a b williams", "e g", "z z specialists"]
y = ["j j winston", "hb d party supplies", "t t ice cream"]
# replacements
x = [re.sub(r'(\b\w)(\s)(\w\b)', r'\1\3', el) for el in x]
y = [re.sub(r'(\b\w)(\s)(\w\b)', r'\1\3', el) for el in y]
# pd dataframe after the process
df = pd.DataFrame(x,y)
【讨论】:
以上是关于python - 使用 re.sub 删除两个字符之间的空格的主要内容,如果未能解决你的问题,请参考以下文章