Удалить символ степени из строки с помощью Python

Я использую Python для чтения текстового файла данных построчно. Одна из строк содержит символ степени. Я хочу изменить эту часть строки. В моем сценарии используется line = line.replace("TEMP [°C]", "TempC"). Мой код останавливается на этой строке, но вообще не меняет жало и не выдает ошибку. Очевидно, в моей замене есть что-то такое, что скрипт не видит «TEMP [°C]» как существующую в моей строке.

Чтобы вставить знак градуса в мой скрипт, мне пришлось изменить кодировку на UTF-8 в настройках файла IDE. Я включил следующий текст в начало своего сценария.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

Как заменить «TEMP [°C]» на «TempC»?

Я использую Windows 7 и Python 2.7 с Komodo IDE 5.2.

Я попытался запустить предложенный код в оболочке Python в Komodo, и это изменило файл.

# -*- coding: utf-8 -*-
line = "hello TEMP [°C]"
line = line.replace("TEMP [°C]", "TempC")
print(line)
hello TempC

Этот предложенный код в оболочке Python в Komodo вернул это.

line = "TEMP [°C]"
line = line.replace(u"TEMP [°C]", "TempC")
Traceback (most recent call last):
File "<console>", line 0, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 6: ordinal not in range(128)

Однако ни одно из этих предложений не сработало при чтении моего текстового файла.

Ваш код отлично работает для меня в интерактивном режиме Python 2.7.

Prune 01.03.2019 01:02

Вы открываете файл с помощью простого open или используете io.open для правильного/автоматического декодирования в unicode? И какая кодировка файла, из которого вы читаете? Если вы используете обычный open, читая из файла, отличного от UTF-8, вы получите другой str, чем тот, который вы получили здесь ("TEMP [°C]" на самом деле 'TEMP [\xc2\xb0C]', но если файл, из которого вы читаете, latin-1 , вы бы прочитали в 'TEMP [\xb0C]' (обратите внимание на отсутствие \xc2, которого требует представление utf-8).

ShadowRanger 01.03.2019 01:17

@GBG: редактирование просто предполагает, даже более убедительно, что кодировка файла не является UTF-8. Является ли Windows или UNIX-подобным? Если второе, попробуйте запустить file NAMEOFYOURINPUTFILE в командной строке; Я предполагаю, что это говорит вам что-то вроде NAMEOFYOURINPUTFILE: ISO-8859 text, а не текст utf-8.

ShadowRanger 01.03.2019 01:28

@ShadowRanger. Я использовал ссылку ниже, чтобы определить, что файл, который я читаю, использует кодировку ANSI. Я попытался добавить import io и открыть файл с помощью io.open, но строка не изменилась.stackoverflow.com/questions/3710374/…

GBG 01.03.2019 01:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
4
2 196
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы должны использовать флаг u для строкового литерала Unicode:

line = line.replace(u"TEMP [°C]", "TempC")

@mrk - я пробовал оба подхода, и ни один из них не работал. Я не понимаю, почему они не работают.

GBG 01.03.2019 01:14

Этот код у меня работает нормально (Python 2.7.14). Может быть, вы можете указать, сделали ли вы что-то другое, чтобы мы могли взять это отсюда.

# -*- coding: utf-8 -*-

line = "hello TEMP [°C]"
line = line.replace("TEMP [°C]", "TempC")

print(line)
# hello TempC

Примечание: Мне не нужен был флаг u.

Ответ принят как подходящий

Основываясь на ваших симптомах, ваши str литералы Python становятся их utf-8 кодировками, поэтому, когда вы вводите:

"TEMP [°C]"

вы на самом деле получаете:

'TEMP [\xc2\xb0C]'

Ваш файл имеет другую кодировку (например, latin-1 или cp1252), и, поскольку вы читаете его через обычный open, вы получаете обратно некодированный str. Но в кодировках latin-1 и cp1252str — это 'TEMP [\xb0C]' (обратите внимание на отсутствие \xc2), поэтому сравнение str не считает две строки эквивалентными.

Лучшее решение — заменить использование open на io.open, в котором используется версия open для Python 3, которая может беспрепятственно декодировать с использованием заданной кодировки для создания канонических представлений unicode, и аналогичным образом использовать литералы unicode вместо str в (для Python) кодировка неизвестна, поэтому нет разногласий по поводу правильного представления символа степени (в unicode есть одно и только одно представление):

import io

with io.open('myfile.txt', encoding='cp1252') as f:
    for line in f:
        line = line.replace(u"TEMP [°C]", u"TempC")

Как вы описываете в своих изменениях, ваш файл, скорее всего, cp1252 (ваш редактор говорит, что это ANSI, это просто глупый способ описать cp1252), поэтому выбран encoding.

Примечание. Если вы собираетесь использовать unicode последовательно во всей своей программе (достойная идея, если вы имеете дело с данными, отличными от ASCII), вы можете сделать это по умолчанию:

from __future__ import unicode_literals
# All string literals are unicode literals unless prefixed with b, as on Python 2

from io import open  # open is now Python 3's open

# No need to qualify with `io.` for `open`, nor put `u` in front of Unicode text
with open('myfile.txt', encoding='cp1252') as f:
    for line in f:
        line = line.replace("TEMP [°C]", "TempC")

На самом деле вам следует просто перейти на Python 3, где вся эта проблема «unicode и str пытаются работать вместе и часто терпят неудачу» была решена путем полного разделения двух типов.

@GBG: Рад, что смог помочь. Если я когда-нибудь заставлю свою машину времени работать, я вернусь в 1980-е и заставлю всех с самого начала переключиться на UTF-8 как на единственную истинную кодировку текста, чтобы мы не застряли, имея дело с Windows и ее локалью. специальные ASCII-надмножества кодировок один байт на символ, которые ничего не делают, но причиняют вам боль в тот момент, когда вам нужна одна не-ASCII-вещь в вашей программе.

ShadowRanger 01.03.2019 01:45

Другие вопросы по теме