2012-01-27 67 views
1

有没有办法从文件中删除非ASCII字符(不是字符)?因此,考虑这样的事情:从文件中删除非ASCII *行*

Line 1 (full ASCII character set) 
Line 2 (contains unicode characters) 
Line 3 (full ASCII) 
Line 4 (contains unicode characters) 

我想:

Line 1 
Line 3 

我知道我可以使用iconv删除ASCII字符,但我想删除包含非ASCII码的任意行。有没有实用/ pythonic的方式来做到这一点?

+1

当你说“完整的ASCII字符集”,你的意思是它包括从0到127的每个字节值?因此,只要没有字节是128或更高的字符,行就可以包含删除,垂直标签,表单提要,空字节等等。 – ruakh 2012-01-27 15:44:18

回答

3

如果你想消除包含任何非ASCII字符的行:

def ascii_lines(iterable): 
    for line in iterable: 
     if all(ord(ch) < 128 for ch in line): 
      yield line 

f = open('somefile.txt') 
for line in ascii_lines(f): 
    print line 
1
LC_ALL=C grep -v $'[^\t\r -~]' 

grep -v版画是匹配模式的所有线路。 LC_ALL=C将区域设置设置为“C”。 $'[^\t\r -~]'是一种模式,在C语言环境中,意思是“包含不是水平制表符,换行符,空格或ASCII字形字符的字符”。 ($'...'是Bash符号:它相当于'...',不同之处在于它处理反斜杠转义,如\t\r[^...]是一个“否定字符类”,意思是“任何未列在...中的字符。 -一个范围相匹配:在这种情况下,范围从空间,波浪线之后的C语言环境是必要的,使这个“范围”的意义上)

2

给定的字符串,如下一页:

>>> s = "asd\n\xaa\xfa\xaf\nqwe" 
>>> print s 
asd 
╙З╞ 
qwe 

您可能只需按照您的标准过滤即可:

>>> s = filter(lambda x: ord(x) < 128, s) 
>>> s 
'asd\n\nqwe' 
>>> print s 
asd 

qwe 

你也可以转换为unicode达到相同的结果:

>>> str(s.decode('ascii', 'ignore')) 
'asd\n\nqwe' 

要删除空行我会使用re.sub('\n+', '\n', s)

+0

你忘了测试''asd \ n123 \ xaa \ xfa \ xaf123 \ nqwe''你的版本产生错误的结果。 – glglgl 2012-01-27 16:33:31

2
for line in fin: 
    try: 
     fout.write(line.encode('ASCII')) 
    except UnicodeDecodeError: 
     pass 
+1

'除了UnicodeEncodeError'会更好,迄今为止 – glglgl 2012-01-27 16:34:02

+0

@glglgl,当然你是对的,事实上这就是我用来测试我的答案。不知何故,它在翻译中迷失了方向。 – 2012-01-27 16:35:44

1

在实践中你会想要做东西与数据,以及需要进一步解析它。如果你的文件test看起来像

http://example.com dog 
http://example.com/å%20ä%20ö/ foo 
http://google.com bar 

一个pyparsing脚本会删除坏线,像这样

from pyparsing import * 

ParserElement.setDefaultWhitespaceChars(" \t") 
EOL = LineEnd() 
ascii = u''.join(unichr(x) for x in xrange(33,127)) 
words = Word(ascii) 
good_line = Group(ZeroOrMore(words) + EOL) 
bad_line = SkipTo(EOL,include=True) 

blocks = good_line | bad_line.suppress() 
grammar = ZeroOrMore(blocks) + StringEnd() 

P = grammar.parseFile("test") 
print P 

这将使作为输出:

[['http://example.com', 'dog', '\n'], ['http://google.com', 'bar']] 

的优势,以其他方法(哪些工作正常,并回答问题),因为你现在有一个很好的分析树来进一步处理数据。这个想法是写一个语法,而不是解析器,对于任何可能在第一次启动时变得更加复杂的任务。