代码之家  ›  专栏  ›  技术社区  ›  Mark van Lent

在Python中从字符串中剥离除字母数字字符以外的所有内容

  •  259
  • Mark van Lent  · 技术社区  · 17 年前

    使用Python从字符串中删除所有非字母数字字符的最佳方法是什么?

    报告中提出的解决方案 PHP variant of this question 可能会有一些小的调整,但对我来说不是很“蟒蛇”。

    为了记录在案,我不仅要去掉句号和逗号(以及其他标点符号),还要去掉引号、括号等。

    10 回复  |  直到 5 年前
        1
  •  393
  •   borgr Atterratio    7 年前

    出于好奇,我刚刚对一些功能进行了计时。在这些测试中,我将从字符串中删除非字母数字字符 string.printable (内置的一部分) string 模块)。汇编语言的使用 '[\W_]+' pattern.sub('', str) 被发现是最快的。

    $ python -m timeit -s \
         "import string" \
         "''.join(ch for ch in string.printable if ch.isalnum())" 
    10000 loops, best of 3: 57.6 usec per loop
    
    $ python -m timeit -s \
        "import string" \
        "filter(str.isalnum, string.printable)"                 
    10000 loops, best of 3: 37.9 usec per loop
    
    $ python -m timeit -s \
        "import re, string" \
        "re.sub('[\W_]', '', string.printable)"
    10000 loops, best of 3: 27.5 usec per loop
    
    $ python -m timeit -s \
        "import re, string" \
        "re.sub('[\W_]+', '', string.printable)"                
    100000 loops, best of 3: 15 usec per loop
    
    $ python -m timeit -s \
        "import re, string; pattern = re.compile('[\W_]+')" \
        "pattern.sub('', string.printable)" 
    100000 loops, best of 3: 11.2 usec per loop
    
        2
  •  329
  •   user1767754    8 年前

    正则表达式来拯救:

    import re
    re.sub(r'\W+', '', your_string)
    

    根据Python定义 '\W == [^a-zA-Z0-9_] ,不包括所有 numbers , letters _

        3
  •  73
  •   John Machin Santi    17 年前

    使用 str.translate()

    delchars = ''.join(c for c in map(chr, range(256)) if not c.isalnum())
    

    (2) 无论何时,只要您想要收紧字符串:

    scrunched = s.translate(None, delchars)
    

    与重新编译相比,安装成本可能更高;边际成本要低得多:

    C:\junk>\python26\python -mtimeit -s"import string;d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s=string.printable" "s.translate(None,d)"
    100000 loops, best of 3: 2.04 usec per loop
    
    C:\junk>\python26\python -mtimeit -s"import re,string;s=string.printable;r=re.compile(r'[\W_]+')" "r.sub('',s)"
    100000 loops, best of 3: 7.34 usec per loop
    

    注: 使用string.printable作为基准数据会给模式“[\W_]+”带来不公平的优势 ; 所有的非字母数字字符都在一组中。。。在典型数据中,需要进行多个替换:

    C:\junk>\python26\python -c "import string; s = string.printable; print len(s),repr(s)"
    100 '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
    

    下面是如果您给re.sub多一点工作要做的情况:

    C:\junk>\python26\python -mtimeit -s"d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s='foo-'*25" "s.translate(None,d)"
    1000000 loops, best of 3: 1.97 usec per loop
    
    C:\junk>\python26\python -mtimeit -s"import re;s='foo-'*25;r=re.compile(r'[\W_]+')" "r.sub('',s)"
    10000 loops, best of 3: 26.4 usec per loop
    
        4
  •  51
  •   ars    17 年前

    print ''.join(ch for ch in some_string if ch.isalnum())
    
        5
  •  18
  •   DisplacedAussie    17 年前
    >>> import re
    >>> string = "Kl13@£$%[};'\""
    >>> pattern = re.compile('\W')
    >>> string = re.sub(pattern, '', string)
    >>> print string
    Kl13
    
        6
  •  15
  •   DrAl    17 年前

    def ExtractAlphanumeric(InputString):
        from string import ascii_letters, digits
        return "".join([ch for ch in InputString if ch in (ascii_letters + digits)])
    

    这是通过使用列表理解来生成一个列表中的字符 InputString 如果它们存在于合并的 ascii_letters digits 串。然后,它将列表合并成一个字符串。

        7
  •  7
  •   Tom Kalvijn    7 年前
    sent = "".join(e for e in sent if e.isalpha())
    
        8
  •  6
  •   BuvinJ Felix    9 年前

    作为其他答案的衍生,我提供了一种非常简单和灵活的方法来定义一组您希望限制字符串内容的字符。在本例中,我允许字母数字加上破折号和下划线。只需添加或删除我的 PERMITTED_CHARS 适合您的用例。

    PERMITTED_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-" 
    someString = "".join(c for c in someString if c in PERMITTED_CHARS)
    
        9
  •  4
  •   Solomon Ucko    7 年前

    使用ASCII可打印文件的随机字符串计时:

    from inspect import getsource
    from random import sample
    import re
    from string import printable
    from timeit import timeit
    
    pattern_single = re.compile(r'[\W]')
    pattern_repeat = re.compile(r'[\W]+')
    translation_tb = str.maketrans('', '', ''.join(c for c in map(chr, range(256)) if not c.isalnum()))
    
    
    def generate_test_string(length):
        return ''.join(sample(printable, length))
    
    
    def main():
        for i in range(0, 60, 10):
            for test in [
                lambda: ''.join(c for c in generate_test_string(i) if c.isalnum()),
                lambda: ''.join(filter(str.isalnum, generate_test_string(i))),
                lambda: re.sub(r'[\W]', '', generate_test_string(i)),
                lambda: re.sub(r'[\W]+', '', generate_test_string(i)),
                lambda: pattern_single.sub('', generate_test_string(i)),
                lambda: pattern_repeat.sub('', generate_test_string(i)),
                lambda: generate_test_string(i).translate(translation_tb),
    
            ]:
                print(timeit(test), i, getsource(test).lstrip('            lambda: ').rstrip(',\n'), sep='\t')
    
    
    if __name__ == '__main__':
        main()
    

           Time       Length                           Code                           
    6.3716264850008880  00  ''.join(c for c in generate_test_string(i) if c.isalnum())
    5.7285426190064750  00  ''.join(filter(str.isalnum, generate_test_string(i)))
    8.1875841680011940  00  re.sub(r'[\W]', '', generate_test_string(i))
    8.0002205439959650  00  re.sub(r'[\W]+', '', generate_test_string(i))
    5.5290945199958510  00  pattern_single.sub('', generate_test_string(i))
    5.4417179649972240  00  pattern_repeat.sub('', generate_test_string(i))
    4.6772285089973590  00  generate_test_string(i).translate(translation_tb)
    23.574712151996210  10  ''.join(c for c in generate_test_string(i) if c.isalnum())
    22.829975890002970  10  ''.join(filter(str.isalnum, generate_test_string(i)))
    27.210196289997840  10  re.sub(r'[\W]', '', generate_test_string(i))
    27.203713296003116  10  re.sub(r'[\W]+', '', generate_test_string(i))
    24.008979928999906  10  pattern_single.sub('', generate_test_string(i))
    23.945240008994006  10  pattern_repeat.sub('', generate_test_string(i))
    21.830899796994345  10  generate_test_string(i).translate(translation_tb)
    38.731336012999236  20  ''.join(c for c in generate_test_string(i) if c.isalnum())
    37.942474347000825  20  ''.join(filter(str.isalnum, generate_test_string(i)))
    42.169366310001350  20  re.sub(r'[\W]', '', generate_test_string(i))
    41.933375883003464  20  re.sub(r'[\W]+', '', generate_test_string(i))
    38.899814646996674  20  pattern_single.sub('', generate_test_string(i))
    38.636144253003295  20  pattern_repeat.sub('', generate_test_string(i))
    36.201238164998360  20  generate_test_string(i).translate(translation_tb)
    49.377356811004574  30  ''.join(c for c in generate_test_string(i) if c.isalnum())
    48.408927293996385  30  ''.join(filter(str.isalnum, generate_test_string(i)))
    53.901889764994850  30  re.sub(r'[\W]', '', generate_test_string(i))
    52.130339455994545  30  re.sub(r'[\W]+', '', generate_test_string(i))
    50.061149017004940  30  pattern_single.sub('', generate_test_string(i))
    49.366573111998150  30  pattern_repeat.sub('', generate_test_string(i))
    46.649754120997386  30  generate_test_string(i).translate(translation_tb)
    63.107938601999194  40  ''.join(c for c in generate_test_string(i) if c.isalnum())
    65.116287978999030  40  ''.join(filter(str.isalnum, generate_test_string(i)))
    71.477421126997800  40  re.sub(r'[\W]', '', generate_test_string(i))
    66.027950693998720  40  re.sub(r'[\W]+', '', generate_test_string(i))
    63.315361931003280  40  pattern_single.sub('', generate_test_string(i))
    62.342320287003530  40  pattern_repeat.sub('', generate_test_string(i))
    58.249303059004890  40  generate_test_string(i).translate(translation_tb)
    73.810345625002810  50  ''.join(c for c in generate_test_string(i) if c.isalnum())
    72.593953348005020  50  ''.join(filter(str.isalnum, generate_test_string(i)))
    76.048324580995540  50  re.sub(r'[\W]', '', generate_test_string(i))
    75.106637657001560  50  re.sub(r'[\W]+', '', generate_test_string(i))
    74.681338128997600  50  pattern_single.sub('', generate_test_string(i))
    72.430461594005460  50  pattern_repeat.sub('', generate_test_string(i))
    69.394243567003290  50  generate_test_string(i).translate(translation_tb)
    

    str.maketrans & str.translate re.compile & pattern.sub 速度较慢,但不知何故比 ''.join filter .

        10
  •  2
  •   Mark van Lent    7 年前
    for char in my_string:
        if not char.isalnum():
            my_string = my_string.replace(char,"")
    
        11
  •  0
  •   Ben Pritchard    5 年前

    对于简单的单行程序(Python 3.0):

    ''.join(filter( lambda x: x in '0123456789abcdefghijklmnopqrstuvwxyz', the_string_you_want_stripped ))
    

    对于Python<3.0:

    filter( lambda x: x in '0123456789abcdefghijklmnopqrstuvwxyz', the_string_you_want_stripped )
    

    注意:如果需要,您可以将其他字符添加到允许的字符列表中(例如“0123456789abcdefghijklmnopqrstuvwxyz.”。

        12
  •  -3
  •   Abhishek Pratap Singh    6 年前

    如果我理解正确,最简单的方法是使用正则表达式,因为它为您提供了很多灵活性,但另一个简单的方法是使用for循环,下面是示例代码,我还计算了单词的出现次数并存储在字典中。。

    s = """An... essay is, generally, a piece of writing that gives the author's own 
    argument — but the definition is vague, 
    overlapping with those of a paper, an article, a pamphlet, and a short story. Essays 
    have traditionally been 
    sub-classified as formal and informal. Formal essays are characterized by "serious 
    purpose, dignity, logical 
    organization, length," whereas the informal essay is characterized by "the personal 
    element (self-revelation, 
    individual tastes and experiences, confidential manner), humor, graceful style, 
    rambling structure, unconventionality 
    or novelty of theme," etc.[1]"""
    
    d = {}      # creating empty dic      
    words = s.split() # spliting string and stroing in list
    for word in words:
        new_word = ''
        for c in word:
            if c.isalnum(): # checking if indiviual chr is alphanumeric or not
                new_word = new_word + c
        print(new_word, end=' ')
        # if new_word not in d:
        #     d[new_word] = 1
        # else:
        #     d[new_word] = d[new_word] +1
    print(d)
    

    如果这个答案有用,请给它打分!