ChatGPT解决这个技术问题 Extra ChatGPT

从字符串中删除所有特殊字符、标点符号和空格

我需要从字符串中删除所有特殊字符、标点符号和空格,以便我只有字母和数字。


w
wjandrea

这可以在没有正则表达式的情况下完成:

>>> string = "Special $#! characters   spaces 888323"
>>> ''.join(e for e in string if e.isalnum())
'Specialcharactersspaces888323'

您可以使用 str.isalnum

S.isalnum() -> bool 如果 S 中的所有字符都是字母数字并且 S 中至少有一个字符,则返回 True,否则返回 False。

如果您坚持使用正则表达式,其他解决方案也可以。但是请注意,如果它可以在不使用正则表达式的情况下完成,那是最好的方法。


不使用正则表达式作为经验法则的原因是什么?
@ChrisDutrow 正则表达式比 python 字符串内置函数慢
@DiegoNavarro,但事实并非如此,我对 isalnum() 和正则表达式版本都进行了基准测试,正则表达式版本快 50-75%
在 Python3 中试过这个——它接受 unicode 字符,所以对我来说没用。以 string = "B223323\§§§$3\u445454" 为例。结果? 'B2233233䑔54'
另外:“对于 8 位字符串,此方法取决于语言环境。”!因此,正则表达式替代方案更好!
w
wjandrea

这是一个正则表达式,用于匹配不是字母或数字的字符串:

[^A-Za-z0-9]+

这是执行正则表达式替换的 Python 命令:

re.sub('[^A-Za-z0-9]+', '', mystring)

亲吻:保持简单愚蠢!这比非正则表达式解决方案更短且更易于阅读,并且可能也更快。 (但是,我会添加一个 + 量词来稍微提高它的效率。)
这也删除了单词之间的空格,“great place”->“greatplace”。如何避免?
@Reihan_amn 只需在正则表达式中添加一个空格,它就变成:[^A-Za-z0-9 ]+
我想这不适用于其他语言中的修改字符,例如á,ö,ñ等。我说得对吗?如果是这样,它将如何成为它的正则表达式?
这不适用于西班牙语、德语、丹麦语和其他语言。
t
tuxErrante

更短的方式:

import re
cleanString = re.sub('\W+','', string )

如果您希望单词和数字之间有空格,请将 '' 替换为 ' '


除了 _ 在 \w 中并且是这个问题的上下文中的特殊字符。
取决于上下文 - 下划线对于文件名和其他标识符非常有用,以至于我不将其视为特殊字符,而是将其视为已清理的空间。我通常自己使用此方法。
r'\W+' - 稍微偏离主题(而且非常迂腐),但我建议一个习惯,即所有正则表达式模式都是 raw strings
此过程不将下划线 (_) 视为特殊字符。
删除 _ 的简单更改:r"[^A-Za-z]+" 而不是 r"\W+"
m
mbeacom

TLDR

我为提供的答案计时。

import re
re.sub('\W+','', string)

通常比第二快提供的最佳答案快 3 倍。

使用此选项时应谨慎。某些特殊字符(例如 ø)可能无法使用此方法进行条带化。

看到这一点后,我有兴趣通过找出哪些执行时间最短来扩展所提供的答案,因此我使用 timeit 对照两个示例字符串检查了一些建议的答案:

string1 = '特别的 $#!字符空格 888323'

string2 = '枫糖浆多少钱? 20.99 美元?这是荒谬的!!!'

示例 1

'.join(e for e in string if e.isalnum())

string1 - 结果:10.7061979771

string2 - 结果:7.78372597694

示例 2

import re
re.sub('[^A-Za-z0-9]+', '', string)

string1 - 结果:7.10785102844

string2 - 结果:4.12814903259

示例 3

import re
re.sub('\W+','', string)

string1 - 结果:3.11899876595

string2 - 结果:2.78014397621

上述结果是平均返回的最低结果的乘积:repeat(3, 2000000)

示例 3 可以比示例 1 快 3 倍。


@kkurian如果您阅读了我的答案的开头,这仅仅是对上述先前提出的解决方案的比较。您可能想对原始答案发表评论... stackoverflow.com/a/25183802/2560922
哦,我知道你要去哪里了。完毕!
在处理大型语料库时必须考虑示例 3。
有效的!感谢您的注意。
你能比较一下我的答案吗''.join([*filter(str.isalnum, string)])
G
Grijesh Chauhan

蟒蛇 2.*

我认为只有 filter(str.isalnum, string) 有效

In [20]: filter(str.isalnum, 'string with special chars like !,#$% etcs.')
Out[20]: 'stringwithspecialcharslikeetcs'

蟒蛇 3.*

在 Python3 中,filter( ) 函数将返回一个可迭代对象(而不是与上面不同的字符串)。必须重新加入才能从 itertable 中获取字符串:

''.join(filter(str.isalnum, string)) 

或在连接使用中传递 list (not sure but can be fast a bit)

''.join([*filter(str.isalnum, string)])

注意:在 [*args] 中解包从 Python >= 3.5 开始有效


@Alexey 正确,在 python3 中,mapfilterreduce 返回可迭代对象。仍然在 Python3+ 中,我更喜欢 ''.join(filter(str.isalnum, string))(或在加入使用 ''.join([*filter(str.isalnum, string)]) 时传递列表)而不是接受的答案。
我不确定 ''.join(filter(str.isalnum, string)) 是对 filter(str.isalnum, string) 的改进,至少在阅读方面是这样。这真的是 Pythreenic(是的,你可以使用那个)方式来做到这一点吗?
@TheProletariat 重点是 只是 filter(str.isalnum, string) 不要在 Python3 中返回字符串,因为 Python-3 中的 filter( ) 返回迭代器而不是参数类型,这与 Python-2 不同。+
@GrijeshChauhan,我认为您应该更新您的答案以包括您的 Python2 和 Python3 建议。
p
pkm
#!/usr/bin/python
import re

strs = "how much for the maple syrup? $20.99? That's ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!]',r'',strs)
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)
print nestr

您可以添加更多特殊字符,并且将被替换为 '' 没有任何意义,即它们将被删除。


A
Andrea

与使用正则表达式的其他人不同,我会尝试排除每个不是我想要的字符,而不是明确列举我不想要的字符。

例如,如果我只想要从“a 到 z”(大写和小写)和数字的字符,我会排除其他所有内容:

import re
s = re.sub(r"[^a-zA-Z0-9]","",s)

这意味着“用空字符串替换不是数字的每个字符,或者'a to z'或'A to Z'范围内的字符”。

事实上,如果您在正则表达式的第一个位置插入特殊字符 ^,您将得到否定。

额外提示:如果您还需要将结果小写,则可以使正则表达式更快更容易,只要您现在找不到任何大写字母即可。

import re
s = re.sub(r"[^a-z0-9]","",s.lower())

V
Vlad Bezden

string.punctuation 包含以下字符:

'!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'

您可以使用 translate 和 maketrans 函数将标点符号映射到空值(替换)

import string

'This, is. A test!'.translate(str.maketrans('', '', string.punctuation))

输出:

'This is A test'

Z
Zoe stands with Ukraine
s = re.sub(r"[-()\"#/@;:<>{}`+=~|.!?,]", "", s)

J
John Machin

假设您想要使用正则表达式并且您想要/需要 2to3-ready 的 Unicode 认知 2.x 代码:

>>> import re
>>> rx = re.compile(u'[\W_]+', re.UNICODE)
>>> data = u''.join(unichr(i) for i in range(256))
>>> rx.sub(u'', data)
u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\xaa\xb2 [snip] \xfe\xff'
>>>

B
BioGeek

最通用的方法是使用对每个字符进行分类的 unicodedata 表的“类别”。例如,以下代码仅根据类别过滤可打印字符:

import unicodedata
# strip of crap characters (based on the Unicode database
# categorization:
# http://www.sql-und-xml.de/unicode-database/#kategorien

PRINTABLE = set(('Lu', 'Ll', 'Nd', 'Zs'))

def filter_non_printable(s):
    result = []
    ws_last = False
    for c in s:
        c = unicodedata.category(c) in PRINTABLE and c or u'#'
        result.append(c)
    return u''.join(result).replace(u'#', u' ')

查看上面给出的所有相关类别的 URL。您当然也可以按标点符号类别进行过滤。


每行末尾的 $ 是什么?
如果是复制和粘贴问题,您应该修复它吗?
p
petezurich

对于包含特殊字符的其他语言,如德语、西班牙语、丹麦语、法语等(如德语“元音变音”作为 üäö),只需将这些添加到正则表达式搜索字符串中:

德语示例:

re.sub('[^A-ZÜÖÄa-z0-9]+', '', mystring)

S
Shubham Shewdikar

这将从字符串中删除所有特殊字符、标点符号和空格,并且只包含数字和字母。

import re

sample_str = "Hel&&lo %% Wo$#rl@d"

# using isalnum()
print("".join(k for k in sample_str if k.isalnum()))


# using regex
op2 = re.sub("[^A-Za-z]", "", sample_str)
print(f"op2 = ", op2)


special_char_list = ["$", "@", "#", "&", "%"]

# using list comprehension
op1 = "".join([k for k in sample_str if k not in special_char_list])
print(f"op1 = ", op1)


# using lambda function
op3 = "".join(filter(lambda x: x not in special_char_list, sample_str))
print(f"op3 = ", op3)

j
jjmurre

使用翻译:

import string

def clean(instr):
    return instr.translate(None, string.punctuation + ' ')

警告:仅适用于 ascii 字符串。


版本区别?我用 py3.4 得到 TypeError: translate() takes exactly one argument (2 given)
它仅适用于 Python2.7。有关将 translate 与 Python3 一起使用的信息,请参阅 below 答案。
V
Vinay Kumar Kuresi
import re
my_string = """Strings are amongst the most popular data types in Python. We can create the strings by enclosing characters in quotes. Python treats single quotes the 

与双引号相同。"""

# if we need to count the word python that ends with or without ',' or '.' at end

count = 0
for i in text:
    if i.endswith("."):
        text[count] = re.sub("^([a-z]+)(.)?$", r"\1", i)
    count += 1
print("The count of Python : ", text.count("python"))

D
Dharman

这将删除除空格以外的所有非字母数字字符。

string = "Special $#! characters   spaces 888323"
''.join(e for e in string if (e.isalnum() or e.isspace()))

特殊字符空格 888323


V
Viren Ramani

10 年后,我在下面写了最好的解决方案。您可以从字符串中删除/清除所有特殊字符、标点符号、ASCII 字符和空格。

from clean_text import clean

string = 'Special $#! characters   spaces 888323'
new = clean(string,lower=False,no_currency_symbols=True, no_punct = True,replace_with_currency_symbol='')
print(new)
Output ==> 'Special characters spaces 888323'
you can replace space if you want.
update = new.replace(' ','')
print(update)
Output ==> 'Specialcharactersspaces888323'

A
Art Bindu
function regexFuntion(st) {
  const regx = /[^\w\s]/gi; // allow : [a-zA-Z0-9, space]
  st = st.replace(regx, ''); // remove all data without [a-zA-Z0-9, space]
  st = st.replace(/\s\s+/g, ' '); // remove multiple space

  return st;
}

console.log(regexFuntion('$Hello; # -world--78asdf+-===asdflkj******lkjasdfj67;'));
// Output: Hello world78asdfasdflkjlkjasdfj67

D
Dsw Wds
import re
abc = "askhnl#$%askdjalsdk"
ddd = abc.replace("#$%","")
print (ddd)

你会看到你的结果

'askhnlaskdjalsdk


等等....您导入了 re 但从未使用过它。您的 replace 条件仅适用于该特定字符串。如果你的字符串是 abc = "askhnl#$%!askdjalsdk" 怎么办?我认为除了 #$% 模式外,其他任何东西都不会起作用。可能想调整一下