如何将Twitch IRC响应中的表情解析成字典列表?

2024-05-13 18:18:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我想把一条IRC消息从Twitch解析到一个字典列表,解释emote。在

以下是Twitch的示例:

"Testing. :) Confirmed!"

{"emotes": [(1, (9, 10))]}

它描述有一个ID为1的emote,从字符9到10(字符串的索引为零)。在

我想要以下格式的数据:

^{pr2}$

有没有一种相对干净的方法来实现这一点?在


Tags: 数据字符串id消息示例列表字典格式
2条回答

我不确定你收到的信息是否是这样的:

message = '''\
"Testing. :) Confirmed!"

{"emotes": [(1, (9, 10))]}'''

或者

^{pr2}$

我假设是后者,因为很容易从前者转换为后者。也可能是python表示。你不太清楚。在

有一种更好的方法来解决这个问题:不使用regex,只使用字符串解析:

import json                                                                                                                                                                                                                     

text = 'Testing. :) Confirmed! :P'                                                                                                                                                                                              
print(len(text))                                                                                                                                                                                                                
meta = '{"emotes": [(1, (9, 10)), (2, (23,25))]}'                                                                                                                                                                               
meta = json.loads(meta.replace('(', '[').replace(')', ']'))                                                                                                                                                                     


results = []                                                                                                                                                                                                                    
cur_index = 0                                                                                                                                                                                                                   
for emote in meta['emotes']:                                                                                                                                                                                                    
    results.append({'type': 'text', 'text': text[cur_index:emote[1][0]]})                                                                                                                                                       
    results.append({'type': 'emote', 'text': text[emote[1][0]:emote[1][1]+1],                                                                                                                                                   
                    'id': emote[0]})                                                                                                                                                                                            
    cur_index = emote[1][1]+1                                                                                                                                                                                                   

if text[cur_index:]:                                                                                                                                                                                                            
    results.append({'type': 'text', 'text': text[cur_index:]})                                                                                                                                                                  

import pprint; pprint.pprint(results)      

根据您的评论,数据以自定义格式提供。我从评论中复制/粘贴了几个字符,我不确定输入数据中是否出现了实际上,我希望这部分我做对了。消息中也只有一种类型的emote,所以我不完全确定它如何表示多个不同的emote类型-我希望有一些分隔符而不是多个emote=部分,或者这种方法需要一些大的修改,但是这个应该提供解析而不需要regex。在

from collections import namedtuple


Emote = namedtuple('Emote', ('id', 'start', 'end'))


def parse_emotes(raw):
    emotes = []
    for raw_emote in raw.split('/'):
        id, locations = raw_emote.split(':')
        id = int(id)
        locations = [location.split('-')
                     for location in locations.split(',')]
        for location in locations:
            emote = Emote(id=id, start=int(location[0]), end=int(location[1]))
            emotes.append(emote)
    return emotes

data = r'@badges=moderator/1;color=#0000FF;display-name=2Cubed;emotes=25:6-10,12-16;id=05aada01-f8c1-4b2e-a5be-2534096057b9;mod=1;room-id=82607708;subscriber=0;turbo=0;user-id=54561464;user-type=mod:2cubed!2cubed@2cubed.tmi.twitch.tv PRIVMSG #innectic :Hiya! Kappa Kappa'

meta, msgtype, channel, message = data.split(' ', maxsplit=3)
meta = dict(tag.split('=') for tag in meta.split(';'))
meta['emotes'] = parse_emotes(meta['emotes'])

我找到了一个解决办法,虽然很难看,但很管用。在

import re

packet_expression = re.compile(r'(@.+)? :([a-zA-Z0-9][\w]{2,23})!\2@\2.tmi.twitch.tv PRIVMSG #([a-zA-Z0-9][\w]{2,23}) :(.+)')

def parse_twitch(packet):

    match = re.match(packet_expression, packet)

    items = match.group(1)[1:].split(';')
    tags = dict(item.split('=') for item in items)

    emote_expression = re.compile(r'(\d+):((\d+-\d+,)*\d+-\d+)')
    tags["emotes"] = [
        (int(emotes[0]), (int(start), int(end)))
        for emotes in re.findall(emote_expression, tags.get("emotes", ''))
        for location in emotes[1].split(',')
        for start, end in [location.split('-')]
    ]

    message = match.group(4)
    characters = list(message)

    offset = 0
    for emote in tags["emotes"]:
        characters[emote[1][0]-offset : emote[1][1]-offset+1] = [{
            "type": "emote",
            "text": ''.join(characters[emote[1][0]-offset : emote[1][1]-offset+1]),
            "id": emote[0]
        }]
        offset += emote[1][1] - emote[1][0]

    index = 0
    while any(isinstance(item, str) for item in characters):
        if isinstance(characters[index], str) and isinstance(characters[index+1], str):
            characters[index:index+2] = [characters[index] + characters[index+1]]
        else:
            if isinstance(characters[index], str):
                characters[index] = {"type": "text", "text": characters[index]}
            index += 1

    return characters

相关问题 更多 >