在 Python 中解析 CS:GO 脚本文件

2022-01-15 00:00:00 python format parsing

问题描述

我正在处理来自 CS:GO 的一些脚本文件,我必须从该文件中获取一些有用的信息并将这些数据导入我的 python 应用程序.

I am working with some script files from CS:GO, I have to get some useful information from this file and import this data into my python application.

这里是一个txt数据格式的例子:

Here is an example of the txt data format:

https://steamcdn-a.akamaihd.net/apps/730/scripts/items/items_game.83a9ad4690388868ab33c627af730c43d4b0f0d9.txt

这些值采用随机格式(ColorPosString),但我只需要一个包含所有值的字符串.我需要将此信息放入字典中,例如:

The values are in the random formats (ColorPosString), but i need just a string, which contains all of the values. I need to get this information into the dictionary for example:

print(global_dict['items_game']['game_info']['first_valid_class'])
<<2

我现在正在研究解析器,但我遇到了很多问题.该文件格式是否有现成的解决方案?

I'm working on parser now, but I was faced with a lot of problems. Is there any ready solutions for that file format?


解决方案

这是一个基于 pyparsing 的解析器,它将解析这种格式:

Here is a pyparsing-based parser that will parse this format:

from pyparsing import Suppress, QuotedString, Forward, Group, Dict, ZeroOrMore

LBRACE,RBRACE = map(Suppress, "{}")
qs = QuotedString('"')

# forward-declare value, since this expression will be recursive
# (will contain expressions which use contain value's)
value = Forward()

key_value = Group(qs + value)
struct = LBRACE + Dict(ZeroOrMore(key_value)) + RBRACE

# define content of value using <<= operator
value <<= qs | struct

# define top-level parser
parser = Dict(key_value)

将配置加载到字符串中,并调用 parser.parseString():

Load the config into a string, and call parser.parseString():

sample = open('cs_go_sample.txt').read()
config = parser.parseString(sample)

print config.keys()
for k in config.items_game.keys():
    print '-', k

config.items_game.pprint()

打印:

['items_game']
- sticker_kits
- client_loot_lists
- prefabs
- quest_definitions
- alternate_icons2
- music_definitions
- rarities
- colors
- campaign_definitions
- player_loadout_slots
- quest_schedule
- item_levels
- revolving_loot_lists
- game_info
- pro_players
- recipes
- items_game_live
- paint_kits_rarity
- paint_kits
- qualities
- items
- attributes
- item_sets
- quest_reward_loot_lists
- kill_eater_score_types

[['game_info',
  ['first_valid_class', '2'],
  ['last_valid_class', '3'],
  ['first_valid_item_slot', '0'],
  ['last_valid_item_slot', '54'],
  ['num_item_presets', '4']],
 ['rarities',
  ['default',
   ['value', '0'],
... etc. ...

编辑

如果您希望在解析时将整数值转换为整数,您可以定义解析操作来执行此操作.但是您只想将此(我认为)附加到作为值的引用字符串,而不是作为键的字符串.

If you want the integer values to be converted to ints at parse time, you can define a parse action to do this. But you want to attach this (I think) only to the quoted strings that are values, not the ones that are keys.

# use this code to convert integer values to ints at parse time
key_qs = qs.copy()
value_qs = qs.copy()
def convert_integers(tokens):
    if tokens[0].isdigit():
        tokens[0] = int(tokens[0])
value_qs.setParseAction(convert_integers)

value = Forward()
key_value = Group(key_qs + value)
struct = LBRACE + Dict(ZeroOrMore(key_value)) + RBRACE
value <<= value_qs | struct
parser = Dict(key_value)

现在输出值如下所示:

[['game_info',
  ['first_valid_class', 2],
  ['last_valid_class', 3],
  ['first_valid_item_slot', 0],
  ['last_valid_item_slot', 54],
  ['num_item_presets', 4]],
 ['rarities',
  ['default',
   ['value', 0],
   ['loc_key', 'Rarity_Default'],
   ['loc_key_weapon', 'Rarity_Default_Weapon'],

请注意,整数值不再显示为字符串,而是显示为实际的 Python 整数.

Note that the integer values are not displayed as strings any more, but as actual Python ints.

相关文章