Python - 如何清除文本中的空格

4
在Python中,我有很多包含空格的字符串。我想要清除文本中的所有空格,但是如果在引号内则不清除。
示例输入:
This is "an example text" containing spaces.

And I want to get:

Thisis"an example text"containingspaces.

line.split()不太好,因为它会清除文本中的所有空格。

你有什么推荐吗?


3
您需要进行一定的分析,以使带引号的字符串保持不变 - 但是此处并不清楚。例如,应该尊重'引用的子字符串吗?未闭合的引号应该如何处理? - Gareth Latty
只有空格被接受在这里。 - Tűzálló Földgolyó
谢谢。 我该如何用**替换这些空格? - Tűzálló Földgolyó
那是一个新问题,不是对这个问题的评论。 - Gareth Latty
@TűzállóFöldgolyó 为什么,如果我可以问的话? - Colonel Panic
7个回答

5

对于只使用双引号"的简单情况:

>>> import re
>>> s = 'This is "an example text" containing spaces.'
>>> re.sub(r' (?=(?:[^"]*"[^"]*")*[^"]*$)', "", s)
'Thisis"an example text"containingspaces.'

解释:

[ ]      # Match a space
(?=      # only if an even number of spaces follows --> lookahead
 (?:     # This is true when the following can be matched:
  [^"]*" # Any number of non-quote characters, then a quote, then
  [^"]*" # the same thing again to get an even number of quotes.
 )*      # Repeat zero or more times.
 [^"]*   # Match any remaining non-quote characters
 $       # and then the end of the string.
)        # End of lookahead.

4

可能有比这更优雅的解决方案,但是:

>>> test = "This is \"an example text\" containing spaces."
>>> '"'.join([x if i % 2 else "".join(x.split())
              for i, x in enumerate(test.split('"'))])
'Thisis"an example text"containingspaces.'

我们将文本按引号分割,然后在列表推导式中进行迭代。如果索引是奇数(不在引号内),我们通过拆分和重新连接来删除空格,如果是偶数(在引号内),则不删除。然后我们用引号重新连接整个内容。

4

使用re.findall可能是更易理解/灵活的方法:

>>> s = 'This is "an example text" containing spaces.'
>>> ''.join(re.findall(r'(?:".*?")|(?:\S+)', s))
'Thisis"an example text"containingspaces.'

您可以滥用csv.reader:
>>> import csv
>>> ''.join(next(csv.reader([s.replace('"', '"""')], delimiter=' ')))
'Thisis"an example text"containingspaces.'

或者使用 re.split

>>> ''.join(filter(None, re.split(r'(?:\s*(".*?")\s*)|[ ]', s)))
'Thisis"an example text"containingspaces.'

1
使用正则表达式!
import cStringIO, re
result = cStringIO.StringIO()
regex = re.compile('("[^"]*")')
text = 'This is "an example text" containing spaces.'

for part in regex.split(text):
    if part and part[0] == '"':
        result.write(part)
    else:
        result.write(part.replace(" ", ""))
return result.getvalue()

这里似乎不需要使用StringIO - 为什么不直接使用列表和 "".join() - Gareth Latty
仅仅因为它更快且需要更少的内存。当然,你可以使用“join”。 - Vladimir Lagunov

1
你也可以使用csv来完成这个操作:

import csv

out=[]
for e in csv.reader('This is "an example text" containing spaces. '):
    e=''.join(e)
    if e==' ': continue
    if ' ' in e: out.extend('"'+e+'"')
    else: out.extend(e)

print ''.join(out) 

打印This is "an example text" containing spaces.


0
'"'.join(v if i%2 else v.replace(' ', '') for i, v in enumerate(line.split('"')))

0
quotation_mark = '"'                                                            
space = " "                                                                             
example = 'foo choo boo "blaee blahhh" didneid ei did '                         
formated_example = ''                                                           

if example[0] == quotation_mark:                                                           
    inside_quotes = True                                                       
else:                                                                           
    inside_quotes = False                                                        

for character in example:                                                          
    if inside_quotes != True:                                                   
        formated_example += character                                              
    else:                                                                       
        if character != space:                                                     
            formated_example += character                                          
    if character == quotation_mark:                                                
        if inside_quotes == True:                                               
            inside_quotes = False                                               
        else:                                                                   
            inside_quotes = True                                                

print formated_example

我会为其他答案重复我的评论:“字符串连接最好使用''.join(seq)进行,这是一个O(n)的过程。相比之下,使用“+”或“+=”运算符可能会导致O(n ** 2)的过程,因为每个中间步骤都可能构建新的字符串。CPython 2.4解释器在一定程度上缓解了这个问题;然而,''.join(seq)仍然是最佳实践。”(http://wiki.python.org/moin/PythonSpeed/) - Gareth Latty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接