Pyparsing:如何解析数据然后编辑 .txt 文件中的特定值?

发布于 2024-10-08 23:03:53 字数 785 浏览 3 评论 0原文

我的数据位于 .txt 文件中(不,我无法将其更改为其他格式),它看起来像这样:

varaiablename = value
某事=这个值
youget = the_idea

这是到目前为止我的代码(取自 Pyparsing 中的示例):

from pyparsing import Word, alphas, alphanums, Literal, restOfLine, OneOrMore, \
empty, Suppress, replaceWith

input = open("text.txt", "r")
src = input.read()

# simple grammar to match #define's
ident = Word(alphas + alphanums + "_")
macroDef = ident.setResultsName("name") + "= " + ident.setResultsName("value") + Literal("#") + restOfLine.setResultsName("desc")
for t,s,e in macroDef.scanString(src):
print t.name,"=", t.value

那么我如何告诉我的脚本编辑特定变量的特定值?
示例:
我想更改变量名的值,从 value 更改为 new_value。 所以本质上变量=(我们要编辑的数据)。

我可能应该明确表示,我不想直接进入文件并通过将 value 更改为 new_value 来更改值,但我想解析数据,找到变量,然后给它一个新值。

my data is located in a .txt file (no, I can't change it to a different format) and it looks like this:

varaiablename = value
something = thisvalue
youget = the_idea

Here is my code so far (taken from the examples in Pyparsing):

from pyparsing import Word, alphas, alphanums, Literal, restOfLine, OneOrMore, \
empty, Suppress, replaceWith

input = open("text.txt", "r")
src = input.read()

# simple grammar to match #define's
ident = Word(alphas + alphanums + "_")
macroDef = ident.setResultsName("name") + "= " + ident.setResultsName("value") + Literal("#") + restOfLine.setResultsName("desc")
for t,s,e in macroDef.scanString(src):
print t.name,"=", t.value

So how can I tell my script to edit a specific value for a specific variable?
Example:
I want to change the value of variablename, from value to new_value.
So essentially variable = (the data we want to edit).

I probably should make it clear that I don't want to go directly into the file and change the value by changing value to new_value but I want to parse the data, find the variable and then give it a new value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

遗弃M 2024-10-15 23:03:53

即使您已经选择了另一个答案,让我回答您原来的问题,即如何使用 pyparsing 来做到这一点。

如果您尝试对某些文本正文进行选择性更改,那么transformString是比scanString更好的选择(尽管scanString或searchString可以通过查找匹配文本来验证语法表达式)。当它扫描文本寻找匹配项时,transformString 将对您的输入字符串应用标记抑制或解析操作修改。

# alphas + alphanums is unnecessary, since alphanums includes all alphas
ident = Word(alphanums + "_")
# I find this shorthand form of setResultsName is a little more readable
macroDef = ident("name") + "=" + ident("value")

# define values to be updated, and their new values
valuesToUpdate = {
    "variablename" : "new_value"
    }

# define a parse action to apply value updates, and attach to macroDef
def updateSelectedDefinitions(tokens):
    if tokens.name in valuesToUpdate:
        newval = valuesToUpdate[tokens.name]
        return "%s = %s" % (tokens.name, newval)
    else:
        raise ParseException("no update defined for this definition")
macroDef.setParseAction(updateSelectedDefinitions)

# now let transformString do all the work!
print macroDef.transformString(src)

给出:

variablename = new_value
something = thisvalue
youget = the_idea

Even though you have already selected another answer, let me answer your original question, which was how to do this using pyparsing.

If you are trying to make selective changes in some body of text, then transformString is a better choice than scanString (although scanString or searchString are fine for validating your grammar expression by looking for matching text). transformString will apply token suppression or parse action modifications to your input string as it scans through the text looking for matches.

# alphas + alphanums is unnecessary, since alphanums includes all alphas
ident = Word(alphanums + "_")
# I find this shorthand form of setResultsName is a little more readable
macroDef = ident("name") + "=" + ident("value")

# define values to be updated, and their new values
valuesToUpdate = {
    "variablename" : "new_value"
    }

# define a parse action to apply value updates, and attach to macroDef
def updateSelectedDefinitions(tokens):
    if tokens.name in valuesToUpdate:
        newval = valuesToUpdate[tokens.name]
        return "%s = %s" % (tokens.name, newval)
    else:
        raise ParseException("no update defined for this definition")
macroDef.setParseAction(updateSelectedDefinitions)

# now let transformString do all the work!
print macroDef.transformString(src)

Gives:

variablename = new_value
something = thisvalue
youget = the_idea
痴骨ら 2024-10-15 23:03:53

对于此任务,您不需要使用特殊的实用程序或模块
您需要的是读取行并将它们拆分为列表,因此第一个索引位于左侧,第二个索引位于右侧。
如果您稍后需要这些值,您可能希望将它们存储在字典中。

对于 Python 新手来说,这是一个简单的方法。取消注释行并打印以将其用作调试。

f=open("conf.txt","r")
txt=f.read() #all text is in txt
f.close()

fwrite=open("modified.txt","w")
splitedlines = txt.splitlines():
#print splitedlines 
for line in splitedlines:
    #print line
    conf = line.split('=')
    #conf[0] is what it is on left and conf[1] is what it is on right
    #print conf
    if conf[0] == "youget":
        #we get this
        conf[1] = "the_super_idea" #the_idea is now the_super_idea
    #join conf whit '=' and write
    newline = '='.join(conf)
    #print newline
    fwrite.write(newline+"\n")

fwrite.close()

For this task you do not need to use special utility or module
What you need is reading lines and spliting them in list, so first index is left and second index is right side.
If you need these values later you might want to store them in dictionary.

Well here is simple way, for somebody new in python. Uncomment lines whit print to use it as debug.

f=open("conf.txt","r")
txt=f.read() #all text is in txt
f.close()

fwrite=open("modified.txt","w")
splitedlines = txt.splitlines():
#print splitedlines 
for line in splitedlines:
    #print line
    conf = line.split('=')
    #conf[0] is what it is on left and conf[1] is what it is on right
    #print conf
    if conf[0] == "youget":
        #we get this
        conf[1] = "the_super_idea" #the_idea is now the_super_idea
    #join conf whit '=' and write
    newline = '='.join(conf)
    #print newline
    fwrite.write(newline+"\n")

fwrite.close()
情话墙 2024-10-15 23:03:53

实际上,您应该看看配置解析器模块
它完全解析您的语法(您只需在开头添加 [section] )。

如果您坚持实施,您可以创建一个字典:

dictt = {}
for t,s,e in macroDef.scanString(src):
   dictt[t.name]= t.value
dictt[variable]=new_value

Actually, you should have a look at the config parser module
Which parses exactly your syntax (you need only to add [section] at the beginning).

If you insist on your implementation, you can create a dictionary :

dictt = {}
for t,s,e in macroDef.scanString(src):
   dictt[t.name]= t.value
dictt[variable]=new_value
落花随流水 2024-10-15 23:03:53

ConfigParser

import ConfigParser

config = ConfigParser.RawConfigParser()
config.read('example.txt')

variablename = config.get('variablename', 'float')

如果你没有,它会对你大喊大叫[ section] 标头,但是没关系,你可以伪造一个

ConfigParser

import ConfigParser

config = ConfigParser.RawConfigParser()
config.read('example.txt')

variablename = config.get('variablename', 'float')

It'll yell at you if you don't have a [section] header, though, but it's ok, you can fake one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文