fifostr - 一个 FIFO(先进先出)缓冲区,用于从带有模式匹配回调的双端队列派生的字符串
项目描述
fifostr.py
FIFOStr - 一个 Python 语言字符串库,旨在在流中查找模式,例如串行连接或回溯解析器。FIFOStr 的工作原理是允许将字符插入到 FIFOstr 对象中,该对象被视为 FIFO(先进先出)缓冲区。FIFOstr 对象可以设置为固定大小,以便在插入新字符时删除最后一个字符。
触发模式(字符串、常规表达式或用 Python 编写的客户解析器)可以附加到 FIFOstr 对象。如果在字符串中检测到该模式,则会调用回调函数来触发操作。可以检测到的模式数量没有限制,每个模式都可以有一个单独的回调。
由于 FIFOstr 是一个固定长度的缓冲区,它可以附加到任何具有可预测资源消耗的流。FIFOstr 还支持可变字符注入/可变字符串支持(用于注入/测试模式)。
提供了示例代码和带有 CI 的完整测试套件。请参阅下面的覆盖和测试部分。
逻辑上 FIFOstr 的工作方式如下:
from fifostr import FIFOStr
#initialize from a given string
myString = FIFOStr("this is a test") # initialize with a string
len(myString) == 14 #true
# The FIFOStr function head( int N) returns the the first N characters
myString.head(4) == "this" #true
myString+= " more" # this addes the string " more" to myString, each character is fed in and the last character in the FIFOstr is removed.
#initialize with max fixed length
myString.head(4) == "is a" #true because the string is also a true FIFO and keeps fixed length. Look at example below for more on pattern matching (and multiple pattern matching for more details)
myString = FIFOStr(10) # creates a blank FIFOStr max length FIFOStr of 10 chars
len(myString) # returns 0, there is no data in FIFOstr yet
myString += "This"
len(myString) == 4 # true
myString += " is more stuff" # add characters to end of string
len(myString) == 10 #true
myString == "more stuff" # true, string is at max len of 10 chars
#mutable support
myString[2] == 'd' # in place modification (mutable string)
myString == "mode stuff" # string position[2] is changed
#For pattern matching & triggers see examples section.
最初,一个更轻的版本用于 python 串行终端程序,它允许串行终端解析双方发送/接收的命令。
码型触发功能
内置模式匹配和触发:只需添加/删除模式,然后调用回调函数(例如,如果“看到”模式,则触发该函数)。模式可以是字符串、正则表达式或用户提供的函数(用 python 编写的解析器)。一个模式包括:
- 模式:字符串或编译的正则表达式或用户提供的解析器函数
- 标签:用户为此模式提供的“名称”
- 开始索引:在 fifostr 中开始模式匹配的位置。默认值为 0(对于熟悉正则表达式的人,也接受字符 '^' 作为起始锚点)
- 停止索引:fifostr 中结束模式匹配的位置。默认为 fifostr 的结尾。无论长度如何,字母“$”都具有特殊含义作为字符串的结尾(同样是正则表达式)
- callback_fn :如果找到模式,则调用 fifostr(start:end) 和标签传递给回调函数 (callback('thematchingstring','label'))
- active :默认为 True,设置是否应主动查找此模式
- 可变字符串支持更改内容中间位置字符以查看回调响应。
安装
pip install fifostr # or just pull fifostr.py from the source repository and put in your source path
原始用途
最初是名为“dioterm”的终端程序的一部分(尽管形式更紧凑),该库用于“侦听”串行端口上任一方向的流量。当发现某些模式(例如从主机发送的命令或来自嵌入式微控制器客户端的特殊数据)时,fifostr 将触发回调以执行某些操作。当必须在主机和客户端之间设置命令序列时,这非常有用。许多这些序列基于主机或客户端发送的内容有条件,导致序列测试用例的许多变化,特别是如果这导致主机必须对不相关的进程或硬件进行一些其他调用才能正确回复。
功能性
FIFOStr 是一个字符串,它(从双端队列派生)具有以下属性:
- 在任一端添加/删除字符或字符串
- 可变的(可以将 char 设置为任何值,例如带有 [] 的数组)
- 使用切片、列表或元组来检索成员(就像真正的 str 对象一样)
- 获取头/尾(以 str 形式返回)
- 匹配头/尾 --> 将提供的字符串匹配到头或尾
- 使用模式触发回调 --> 模式可以是字符串 | 正则表达式 | user_supplied_parser 任何触发用户提供的 callback_fn
- 所有模式都可以查看整个 fifostr 或任何子集,例如 addPattern("foo",myCallback,2,5,"bar") --> 仅在 fifostr 中的位置 2 和 5 之间查找“foo”,并将调用 myCallback与 ("foo","bar") 如果找到
- 所有模式都有可用于记录目的的可选标签(例如,当找到模式时,除了回调,发出标签)
- 使用字符串匹配部分和标签调用用户提供的 callback_fn
- 可以从“观看”fifostr 内容的模式列表中添加/删除模式
- 所有(活动)模式总是匹配的。fifostr 匹配同一字符串上的多个不同模式。
- 清除所有模式 --> 从处理中删除模式
- get/setPattern Active/Inactive --> 允许打开或关闭存储的模式
- Python 2.7+,Python 3+ 支持,源自内置 deque 包
- 2.7 和 3.x 中的 100% 测试覆盖率
使用示例
请参阅 example.py 以在测试目录中运行 - 与此处相同的示例,但更多评论,更多用例
from fifostr import FIFOStr
def main():
myFifoStr=FIFOStr(5) #make a fifostr of length 5 (for unlimited length omit number)
myFifoStr+='1234567' #adds 1234567 to fifostr ... but len of fifostr is 5
# so only 34567 is retained
print "myFifoStr.head(3)= ",myFifoStr.head(3) #shows 345
print "myFifoStr.tail(4)= ",myFifoStr.tail(4) #shows 4567
# the eqhead and eqtail functions allow string compares against
# the head or the tail
myFifoStr.eqhead("3456") #True
myFifoStr.eqhead("567") #False
myFifoStr.eqtail("4567") #True
myFifoStr.eqtail("abc") #False
#fifostr.testPattern() allows you to test if the pattern is present in the fifostr object
#test a string pattern directly
myFifoStr.testPattern('67890') #False
#test a regex pattern directly. to do this pass any valid regex in compiled form
r1=re.compile("[0-9]+")
myFifoStr.testPattern(r1) #True
r2=re.compile("[a-z]+")
myFifoStr.testPattern(r2) #False
#more generally we can add (and remove) patterns which will scan and trigger a call back everytime the fifostr
#internal content changes (whether adding or deleting chars from either end or even rotating/reversing the fifstr object)
#adding patterns
p1 = myFifoStr.addPattern("234",logf,label="234 was here") #integer index returned managing pattern
p2 = myFifoStr.addPattern("67890",logf,label="67890 detected")
p3 = myFifoStr.addPattern(r1,logf,label="r1 detected")
myFifoStr.addPattern(r2,logf,label="r2 hit")
myFifoStr.addPattern(f1,logf,label="f1 hit")
myFifoStr.addPattern(f2,logf,label="f2 hit")
#patterns can be set active/inactive via pattern management fns
myFifoStr.setPatternActiveState(p1,False) #based on index returned from addPattern
#now show searching for stored pattern matchers in the pattern dict
#this is not searching the fifo-string itself, just the stored patterns that we have entered
print("find pattern by label 'foo':",myFifoStr.findPatternByLabel("foo")) #no matches returns empty list
print("find pattern by label '234 hit':",myFifoStr.findPatternByLabel("234 hit")) #shows match
print("find pattern by label using regex '[rf][0-9]':")
pp.pprint(myFifoStr.findPatternByLabel(re.compile("[rf][0-9]")))
#and finally demonstrate that patterns auto-trigger when items inserted in fifostr .. which afterall
#is the point of the whole thing.. ;)
print("\n fifo operations ============")
for c in '01234567890abcdefghijklmnop': #show using inc which accomplishes same thing
myFifoStr += c
myFifoStr+= 'abcdefghi'
print (myFifoStr.all())
笔记
FIFOstr 并不意味着替代编译器/解析器前端,尽管它可以用作复杂的标记器。每次将某些内容添加到 fifostr 对象时,内部只是迭代存储的模式。如果您确实有一个您希望被调用的解析器,那么只需将其添加为回调函数,以便每次使用 char(s) 更新 fifostr 时,它都会调用您的解析器来完成工作。如果您希望使用基于回调的触发,您的解析器必须返回一个布尔结果。多个自定义解析器可以与静态字符串模式或正则表达式一起运行。
#let your own parser do the work
myFifo = fifostr(20) # make a 20 char fifostr
myFifo.addPattern(myParser,myCallbk) #myParser passed entire fifostr (as str) when char(s) added
myFifo.addPattern(myParser,myCallbk2,3,5) #myParser passed fifostr btw (3,5). My Parser must return True if match found for callback to be invoked
源代码
所有来源都在 github:
https ://github.com/deftio/fifostr
项目主页
公司主页
https://deftio.com/上的文档和其他项目
测试与覆盖
如需快速使用,请
参阅example.py 文件中的main
为了测试覆盖率,请在 /tests 目录中查看
以运行测试 pytest 需要安装。
在 Ubuntu 上
pip install -U pytest pytest-cov
pip install coveralls
注意:pytest.org 上的更多信息,用于在其他操作系统上安装
# running basic tests
cd tests
pytest #or py.test
# coverage stats below
coverage run --source fifostr -m pytest
coverage report -m
生成文档
文档是使用构建脚本中的 pandoc 和 pydoc 生成的。
sudo apt-get install pandoc
文档位于 /docs 目录(由 pydoc 生成)以(重新)生成文档。cd 到 docs 目录。然后输入:
pydoc -w ../fifostr.py
请注意,在撰写本文时,pydoc 在当前目录中生成其输出,并且似乎无法通过管道传输到另一个目录。
发布历史
- 1.1.19 添加了 sys.displayhook 链接,用于交互模式显示
- 1.1.18 新增 Str 构造函数
- 1.1.17 更新以支持 3.9x
- 1.1.16 更新以在测试中支持 python 3.7 3.8 3.9
- 1.1.15 更新了 PyPi 以使用 README.md 而不是 README.rst(没有其他更改)
- 1.1.10 更新了 repo 的文档和相关使用信息
- 1.1.9 重建 README.md 到 README.rst 的转换,使用 PyPi 的 pandoc(无代码更改)
- 1.1.8 重建以确保将正确的 pkg 加载到 PyPi(无代码更改)
- 1.1.7 更新了 MANIFEST.in 以使用 README.rst
- 1.1.6 在 README.md 中添加了 PyPi 版本标记
- 1.1.5 覆盖率达到 100%,添加了标记,添加了 README.rst
- 1.1.x 将类名从 fifostr 更改为 FIFOStr 以使 PEP8 兼容。修复 setup.py (package_dir) 中的错误
- 1.0.x 文档清理
- 1.0.0 初始版本
README.md 与 README.rst
README.rst 是使用 pandoc 从 README.md 生成的,但内容是相同的。(在早期版本中用于 PyPi)
执照
请参阅此目录中的 LICENSE.txt 文件。该许可证是 OSI 批准的“FreeBSD”2 条款许可证。
(c) 2018 马查特吉
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。