Я новичок в Python и пытаюсь сделать простое приложение редактора конфигурации.
У меня есть .txt
файлы, которые внутри него содержат кучу слов count
, таких как:
...
...
max_count=1000
count=123
host_count=000
...
...
В моем случае я хочу изменить только точное совпадение слов с count=
в качестве ключа к count=0
и любым числом на этом (после знака =
), я хочу заменить его на значение, которое пользователь дал из поля ввода, игнорируя другие значения, такие как max_count=, host_count=, etc
. Возможно ли это сделать?
Например:
Когда пользователь вводит 0 в поле ввода, результатом будет
count=0
Когда пользователь вводит 1 в поле ввода, результатом будет
count=1
Другие
xxx_count=
илиcount_xxx=
будут игнорироваться
Я попытался сделать это, как показано ниже, но все подсчеты заменены, а не только слова совпадений count=
.
files = Finder(self.path, self.name).find()
for file in files:
with open(file) as target:
content = target.read()
if self.target in content:
print(content)
content = content.replace(self.target, self.value)
with open(file, "w") as target:
target.write(content)
else:
print('{} not found in {}'.format(self.target, file))
Пожалуйста помоги.
ОБНОВЛЕНИЕ
Вот мой класс Finder (он используется только для поиска файлов).
import os
class Finder:
result = []
"""
Create new instance.
:param {string} path: the directory of the target file.
:param {string} name: the name of the file.
"""
def __init__(self, path, name):
self.path = path
self.name = name
# Find files in the given path.
def find(self):
directory_exists = os.path.isdir(self.path)
if not directory_exists:
return print('Tidak dapat menemukan file {} di folder: {}.'.format(self.name, self.path))
for root, dirs, files in os.walk(self.path):
for file in files:
if self.name in file:
self.result.append(os.path.join(root, file))
return self.result
И это полная версия моего Modifier
класса:
from modules.Finder import Finder
from pprint import pprint
class Modifier(Finder):
"""
Create new instance.
:param target: target to be modified.
:param value: value to be used on target.
"""
def __init__(self, path, name, target, value):
self.target = target
self.value = value
Finder.__init__(self, path, name)
def modify(self):
files = Finder(self.path, self.name).find()
if not files:
return files
for file in files:
with open(file) as target:
content = target.read()
if self.target in content:
print(content)
content = content.replace(self.target, self.value)
with open(file, "w") as target:
target.write(content)
else:
print('{} not found in {}'.format(self.target, file))
ОБНОВЛЕНИЕ 2
Просто чтобы убедиться, что все понимают, что я хочу сделать. Это мой App.py
файл, который контролирует программу.
from pprint import pprint
from modules.Modifier import Modifier
SMSGW = Modifier('D:\\Smsgw', 'SMSGW.ini', 'count=', 'count=0')
settings = SMSGW.modify()
pprint(settings)
3 ответа
Используйте регулярное выражение ^count=\d+$
для замены точного соответствия count=somenumber
Принимая во внимание : user_input
- ввод, введенный пользователем, а content
- данные, считанные из файла.
import re
re.sub(r'^count=\d+$', 'count={}'.format(user_input), content)
Я вижу, что в большинстве случаев вы используете оператор in
для проверки строк. Как здесь:
if self.name in file:
Или здесь
if self.target in content:
Я думаю, что это не то, что вам нужно. Операторы in
проверяют, содержится ли строка в других строках, например, 'a' in 'bac'
возвращает True
. А также count=
в max_count=
возвращает True
. Так что проблема может возникнуть отсюда.
Я думаю, вам нужно проверить на точное равенство, поэтому вы должны изменить эти строки в:
if self.name == file:
Или
if self.target == content:
Теперь, чтобы использовать это решение, вам нужно отделить значение от цели. Используйте метод split.
Например, если content
равен "count=123"
, вы можете сделать:
sepcontent = content.split('=')
Это создаст список sepcontent
, который будет ['count', '0']
. Вы можете проверить равенство в первом элементе if self.target == sepcontent[0]
.
И вам определенно нужно повторять построчно при этом. Поэтому не используйте target.read()
, который создаст единственную строку из полного файла.
В конце у вас должно получиться что-то вроде:
wfile = 'tempfile.txt'
with open(file) as target:
with open(wfile, 'w') as wtarget:
for content in target:
sepcontent = content.split("=")
if sepcontent[0] == "count": #or your self.target
content = content.replace(spline[1], self.value)
wtarget.write(content)
В конце у вас будут все ваши правки в файле с именем tempfile.txt
. Вы можете просто переименовать этот файл, чтобы заменить оригинал.
Я не буду точно следовать вашему коду, однако решение вашего основного вопроса, похоже, использует регулярные выражения.
Если ваша строка s = 'x_count=1\ncount=0\ncount_xx=0'
или
x_count=1
count=0
count_xx=0
Вы можете использовать регулярное выражение, чтобы найти и заменить число после count=
import re
s = 'x_count=1\ncount=0\ncount_xx=0'
## user inputs the number 1, so we replace the current number with 1
new_s = re.sub(r'\ncount=(\d)', r'\ncount=1', s)
Дайте мне знать, если это полезно или нет!
Редактировать:
import re
user_input = 1
for file_name in list_of_file_names:
with open(file_name) as f:
new_file_content= re.sub(r'\ncount=(\d)', r'\ncount=%d'(user_input), f.read())
with open(file_name, "w") as f:
f.write(new_file_content)
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.