2012-01-27 5 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

ответ

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

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

'except UnicodeEncodeError' будет лучше на сегодняшний день – glglgl

+0

@glglgl, конечно, вы правы, и на самом деле это то, что я использовал при тестировании моего ответа. Как-то он потерялся в переводе. –

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']] 

Преимущество других методов (которые работают нормально и отвечают на вопрос), так как теперь у вас есть красивое дерево синтаксиса для дальнейшего управления данными. Идея состоит в том, чтобы написать грамматику , а не синтаксический анализатор, для любой задачи, которая может стать более сложной, чем при первом запуске.

Смежные вопросы