想做一个东西,cli 或者当 library 都可以用。大概是

python main.py data.csv --transform "parser | get='name' | len==10 | original | parser | get='age'"

做的就是遍历所有行,parse 数据,找到“名字”长度为 10 的行,返回“age”

传输的数据:
class Item:
    orignial: Any
    value: Any

我写了 Parser, Len, GetField, Orignal 这几个 class 。初步计划是事先把 class 放到一个 dict 里,解析字符串为,并把操作符和数值拿来初始化 class

pipe_units = [
    Parser(),
    Get("=", "name"),
    Len("==", "10"),
    Original(),
    Parser(),
    Get("=", "name"),
]

然后 pipe = CompiledPipe(pipe_units)

wrapped_records = CsvReader(f) # 也是个 pipe unit

pipe.set_upstream(wrapped_records) # 或者 wrapped_records >> pipe

for out_record in pipe:
    print(out_record)
   
   
这样的做法有什么明显缺陷吗?解析 pipe 字符串有什么比较好的方法吗?现在直接用 split 之类的方法来做,感觉很粗糙。这个 parse 动作,在业界有专有名词吗?谢谢各位
举报· 99 次点击
登录 注册 站外分享
6 条回复  
fgwmlhdkkkw 小成 2024-8-15 12:03:41
试试这个

https://github.com/lark-parser/lark
ipwx 小成 2024-8-15 12:08:55
写 dsl 可以用 pyparsing
liberize 小成 2024-8-15 12:36:28
如果 get 后面的 name 里包含'|',直接用 split 有问题。
GeekGao 小成 2024-8-15 13:01:42
```
from pyparsing import Word, alphanums, Suppress, Group, OneOrMore, Optional

def parse_pipeline(pipeline_string):
    # 定义基本元素
    command = Word(alphanums + "_")
    argument = Word(alphanums + "_='")
    pipe = Suppress("|")
   
    # 定义命令结构
    command_structure = Group(command + Optional(Group(OneOrMore(argument))))
   
    # 定义整个管道结构
    pipeline = OneOrMore(command_structure + Optional(pipe))
   
    # 解析字符串
    parsed = pipeline.parseString(pipeline_string)
   
    result = []
    for item in parsed:
        if len(item) == 1:
            result.append({"command": item[0], "args": []})
        else:
            result.append({"command": item[0], "args": item[1].asList()})
   
    return result

# 使用
pipeline_str = "parser | get='name' | len==10 | original | parser | get='age'"
parsed_pipeline = parse_pipeline(pipeline_str)
print(parsed_pipeline)

```


Output:
```
[{'command': 'parser', 'args': []}, {'command': 'get', 'args': ["='name'"]}, {'command': 'len', 'args': ['==10']}, {'command': 'original', 'args': []}, {'command': 'parser', 'args': []}, {'command': 'get', 'args': ["='age'"]}]
```

抛砖引玉。
rming 小成 2024-8-15 13:25:01
awk 可解,就是学习成本有点高
june4 小成 2024-8-15 13:49:49
格式这么简单有序的东西,完全没必要手写分析器从一个个字符处理,split 加正则才是正道,除非你本意是想学点新东西
返回顶部