这个主题与Parsing a CS:GO script file in Python主题有关,但还有另一个问题。我正在编写CS的一个内容:GO,现在我正在尝试制作一个python工具,将/script/文件夹中的所有数据导入Python字典。
解析数据后的下一步是从/resources解析语言资源文件,并在字典和语言之间建立关系。
有一个用于Eng本地化的原始文件:english.txt
文件格式与以前的任务类似,但我面临另一个问题。所有的语言文件都是用UTF-16-LE编码,我无法理解用Python处理编码文件和字符串的方法(我主要是使用Java),我尝试过基于open(fileName, encoding='utf-16-le').read()制定一些解决方案,但是我不知道如何在Python解析中处理这样的编码字符串。
pyparsing.ParseException:预期引号字符串,以“结尾”开头(字符0),(行:1,col:1)
另一个问题是带有\"-like表达式的行,例如:
"musickit_midnightriders_01_desc" "\"HAPPY HOLIDAYS, ****ERS!\"\n -Midnight Riders"如果我想保持这些符号的原样,如何解析这些符号?
发布于 2016-03-12 20:09:47
这个输入文件有一些新的缺陷,不在原始CS:GO示例中:
\"在某些值字符串中转义引号[$WIN32]、[$OSX])结尾。前两个问题是通过修改value_qs的定义来解决的。由于值现在比键功能更全面,所以我决定为它们使用单独的QuotedString定义:
key_qs = QuotedString('"').setName("key_qs")
value_qs = QuotedString('"', escChar='\\', multiline=True).setName("value_qs")第三个问题需要更多的重构。这些限定条件的使用类似于C中的#IFDEF宏--只有当环境与条件匹配时,它们才启用/禁用定义。其中一些条件甚至是布尔表达式:
[!$PS3][$WIN32||$X360||$OSX][!$X360&&!$PS3]这可能导致定义文件中的重复键,如以下几行:
"Menu_Dlg_Leaderboards_Lost_Connection" "You must be connected to Xbox LIVE to view Leaderboards. Please check your connection and try again." [$X360]
"Menu_Dlg_Leaderboards_Lost_Connection" "You must be connected to PlayStation®Network and Steam to view Leaderboards. Please check your connection and try again." [$PS3]
"Menu_Dlg_Leaderboards_Lost_Connection" "You must be connected to Steam to view Leaderboards. Please check your connection and try again."其中包含键"Menu_Dlg_Leaderboards_Lost_Connection“的3个定义,这取决于设置了哪些环境值。
为了在解析文件时不丢失这些值,我选择在解析时通过附加条件来修改键。此代码实现更改:
LBRACK,RBRACK = map(Suppress, "[]")
qualExpr = Word(alphanums+'$!&|')
qualExprCondition = LBRACK + qualExpr + RBRACK
key_value = Group(key_qs + value + Optional(qualExprCondition("qual")))
def addQualifierToKey(tokens):
tt = tokens[0]
if 'qual' in tt:
tt[0] += '/' + tt.pop(-1)
key_value.setParseAction(addQualifierToKey)因此,在上面的示例中,您将得到3个键:
最后,注释的处理可能是最简单的。Pyparsing支持跳过注释,就像空格一样。您只需要为注释定义表达式,顶层解析器就会忽略它。为了支持这一特性,在common解析中预定义了几种常见的注释形式。在这种情况下,解决方案只是将最终的解析器定义更改为:
parser.ignore(dblSlashComment)最后,在QuotedString的实现中存在一个小错误,其中标准空格字符串文本(如\t和\n )不被处理,只是被视为不必要的转义't‘或'n’。所以现在,当这一行被解析时:
"SFUI_SteamOverlay_Text" "This feature requires Steam Community In-Game to be enabled.\n\nYou might need to restart the game after you enable this feature in Steam:\nSteam -> File -> Settings -> In-Game: Enable Steam Community In-Game\n" [$WIN32]对于您刚刚得到的值字符串:
This feature requires Steam Community In-Game to be enabled.nnYou
might need to restart the game after you enable this feature in
Steam:nSteam -> File -> Settings -> In-Game: Enable Steam Community
In-Gamen而不是:
This feature requires Steam Community In-Game to be enabled.
You might need to restart the game after you enable this feature in Steam:
Steam -> File -> Settings -> In-Game: Enable Steam Community In-Game我将不得不在下一版本的pyparsing解析中修复此行为。
下面是最后的解析器代码:
from pyparsing import (Suppress, QuotedString, Forward, Group, Dict,
ZeroOrMore, Word, alphanums, Optional, dblSlashComment)
LBRACE,RBRACE = map(Suppress, "{}")
key_qs = QuotedString('"').setName("key_qs")
value_qs = QuotedString('"', escChar='\\', multiline=True).setName("value_qs")
# use this code to convert integer values to ints at parse time
def convert_integers(tokens):
if tokens[0].isdigit():
tokens[0] = int(tokens[0])
value_qs.setParseAction(convert_integers)
LBRACK,RBRACK = map(Suppress, "[]")
qualExpr = Word(alphanums+'$!&|')
qualExprCondition = LBRACK + qualExpr + RBRACK
value = Forward()
key_value = Group(key_qs + value + Optional(qualExprCondition("qual")))
def addQualifierToKey(tokens):
tt = tokens[0]
if 'qual' in tt:
tt[0] += '/' + tt.pop(-1)
key_value.setParseAction(addQualifierToKey)
struct = (LBRACE + Dict(ZeroOrMore(key_value)) + RBRACE).setName("struct")
value <<= (value_qs | struct)
parser = Dict(key_value)
parser.ignore(dblSlashComment)
sample = open('cs_go_sample2.txt').read()
config = parser.parseString(sample)
print (config.keys())
for k in config.lang.keys():
print ('- ' + k)
#~ config.lang.pprint()
print (config.lang.Tokens.StickerKit_comm01_burn_them_all)
print (config.lang.Tokens['SFUI_SteamOverlay_Text/$WIN32'])https://stackoverflow.com/questions/35955019
复制相似问题