在动态分隔符上拆分字符串

时间:2018-10-31 14:27:04

标签: c# regex string split packet

我要处理以下问题。 我必须从通信缓冲区中提取消息。可悲的是,通信协议糟糕透顶且结构不完善。我想出的区分缓冲区中数据包的唯一方法是服务器发送的中间“ ack”命令。

示例:

  

[Packet1] [ACK] [Packet2] [ACK] [Packet3]

我本可以使用String.Split(ACK),但是分隔符也不是一致的。虽然,有3条规则来标识ack数据包。

  1. 以“ AK”开头。
  2. 以“ 0”或“ 1”结尾。
  3. 总长度为5个字符。

确认示例:
“ AKxxy”,其中:
xx :(从01到99)
y:(0或1)

我希望可能会有一个正则表达式可以解决我的问题,但是我缺少所需的知识和时间。

是否有任何RegEx“专家”可能会对我有所帮助?随时提出任何解决方案。
谢谢。

编辑:
示例数据包(我真的必须删除数据包信息):
AK010CONFIDENTIALPACKET1AK011CONFIDENTIALPACKET2AK020AK011CONFIDENTIALPACKET3AK021CONFIDENTIALPACKET4AK050

遗憾的是,协议中的每个数据包都没有以特定字符开头或结尾,因此我无法区分它们。为了识别每一个,我必须使用ack数据包将它们拆分,然后对每一个执行不同的检查。

3 个答案:

答案 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]).)*)

它可以像这样分析文本: enter image description here

您可以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('|');

假设|不是有效的输入字符。您可以选择非常具有异国情调的东西。

相关问题