我要处理以下问题。 我必须从通信缓冲区中提取消息。可悲的是,通信协议糟糕透顶且结构不完善。我想出的区分缓冲区中数据包的唯一方法是服务器发送的中间“ ack”命令。
示例:
[Packet1] [ACK] [Packet2] [ACK] [Packet3]
我本可以使用String.Split(ACK),但是分隔符也不是一致的。虽然,有3条规则来标识ack数据包。
确认示例:
“ AKxxy”,其中:
xx :(从01到99)
y:(0或1)
我希望可能会有一个正则表达式可以解决我的问题,但是我缺少所需的知识和时间。
是否有任何RegEx“专家”可能会对我有所帮助?随时提出任何解决方案。
谢谢。
编辑:
示例数据包(我真的必须删除数据包信息):
AK010CONFIDENTIALPACKET1AK011CONFIDENTIALPACKET2AK020AK011CONFIDENTIALPACKET3AK021CONFIDENTIALPACKET4AK050
遗憾的是,协议中的每个数据包都没有以特定字符开头或结尾,因此我无法区分它们。为了识别每一个,我必须使用ack数据包将它们拆分,然后对每一个执行不同的检查。
答案 0 :(得分:3)
直接翻译为
\bAK\d{2}[01]\b
那是
\b # a word boundary
AK # AK literally
\d{2} # two digits
[01] # one of 0 or 1
\b # another word boundary
不过,表达式需要进行测试(请参见a demo on regex101.com)。
答案 1 :(得分:2)
编辑:
看看其他答案,这可能仅仅是装饰性的价值。 @Jan和@ThymosK的解决方案
var packets = Regex.Split(buffer, @"AK\d{2}[01]");
似乎更加优雅。
但是我认为最好看看如何在正则表达式中移动所有解析。即使它太不可读:P
我设计了一个正则表达式,可以为您提供消息和分隔符分组:
(?s)(AK[0-9][0-9][0,1])|((?:(?!AK[0-9][0-9][0,1]).)*)
您可以here对其进行测试。
和往常一样,正则表达式只能写。我自己几乎看不懂。但我会尽力做到这一点:
第一组简单明了,只需捕获您的ack命令即可:
(AK[0-9][0-9][0,1])
第二组包含否定的前行(?! ... )
,该行与未由...
指定的正则表达式匹配的任何内容匹配。在这里,我们插入您的ack
语法,因此所有不跟ack
的内容都将匹配。然后,我们添加一个字符,以扩展该字符以实际匹配最高ack
的任何字符。
基本上,第二部分断言我们当前不跟随ack
,然后添加一个字符。尽可能长的重复此过程,直到找到ack
。我把它变成第二组。
由于我目前没有C#,因此无法使用C#正则表达式引擎将其包装在代码中。但是python可以很好地工作,并提供了一个有用的findall方法,可以为您提供所有这些组。
答案 2 :(得分:0)
string interim = Regex.Replace(buffer, "AK\d{2}[01]", "|");
var commands = interim.Split('|');
假设|
不是有效的输入字符。您可以选择非常具有异国情调的东西。