pyparsing进行语法解析

使用pyparsing进行对端口表述的语法解析

下面的代码表示的是对各种形式表达的端口进行转换到端口对或端口的形式。

import unittest

from pyparsing import alphas, nums, alphanums, Suppress, Word, CaselessLiteral, \
    OneOrMore, ZeroOrMore, oneOf, Group, Optional, White, \
    stringEnd, ParseException, stringStart, common

text = """123
1 - 555
1-66
1,55
1|55
1、55
1~55
1-88
2or99
11或899
1024, 1025-9999,36525或99999
1024, 1025-9999,   36525"""


def validate_integer_range(a, b):
    """限制范围"""

    def _warp(tokens):
        if a <= tokens.port <= b:
            pass
        else:
            raise ParseException(f'invalid range: {a}-{b}, found:{tokens.port}')

    return _warp


port = Word(nums, max=5, min=1).setResultsName('port')
port.setParseAction(common.convert_to_integer, validate_integer_range(1, 65535))
or_sp = Suppress(oneOf(', | / \\ 、 或'))
range_sp = Suppress(oneOf('- ~ —— -'))
range_port = Group(port + range_sp + port).setResultsName('port_range')
port_present = range_port | port
dsl = ZeroOrMore(port_present + or_sp) + port_present + Optional(or_sp) + stringEnd


class PyDSLTestCase(unittest.TestCase):
    """
    https://zhuanlan.zhihu.com/p/259638397
    https://pyparsing-docs.readthedocs.io/en/latest/HowToUsePyparsing.html#helper-methods
    """

    def test_simple1(self):
        for line in text.splitlines():
            p = dsl.parseString(line)
            # print(p.dump())
            print(p)

    def test_result_name(self):
        s = '1,2,3/ 455-6778'
        p = dsl.parseString(s)
        print(p)


if __name__ == '__main__':
    unittest.main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值