1

我正在尝试为String通过 TCP/IP 套接字进入的所示打击制作正则表达式。

$AVSYS,99999999,V1.17,SN0000103,32768*16

每个字符串应以$ 5 到 6 位数字之间的美元符号和大写字母字符开头。它们以*2 位字母数字校验和结尾。每个字段以逗号分隔,,可以是任何字符串。

我为它创建了一个正则表达式。

^\$[A-Z]{5,6}(\,.*)(\,.*)(\,.*)(\,.*)(\,.*)\*[\d\w]{2}$

我预计它会匹配,但它没有。即使我已经阅读了 Java 文档,我仍然不熟悉正则表达式。请帮助我获得正确的正则表达式。

已编辑

根据回复修复正则表达式后,我尝试了这两个。

^\$[A-Z]{5,6}(\,.*)(\,.*)(\,.*)(\,.*)(\,.*)\*[\d\w]{2}$
^\$[A-Z]{5,6}(\,.*?)(\,.*?)(\,.*?)(\,.*?)\*[\d\w]{2}$

但我得到的结果比我预期的要多。

$AVSYS,99999999,V1.17,SN0000103,32768*16
$AVRMC,80000551,144811,A,4351.3789,N,07923.4712,W,0.00,153.45,091107,A,,161,1*64
$AVRMC,80000551,144811,A,4351.3789,N,07923.4712,W,0.00,153.45,091107,A,,161,1,0,0*64
$EAVSYS,99999999,12345678901234567890,9057621228,,,*0B

以上句子都与正则表达式匹配。但我只想得到1)。我怎样才能做到这一点?

4

3 回答 3

1

要匹配任意数量的逗号分隔组,您可以使用以下表达式:

^\$[A-Z]{5,6}(,[^,*]*)*\*[\da-zA-Z]{2}$

数据部分由以下表达式匹配:

(,[^,*]*)*

它匹配零个或多个以逗号开头的字符组,后跟除逗号或星号以外的任意数量的字符。一旦到达逗号或星号,表达式引擎就会检查它是新值还是最后的校验和。

如果校验和不允许小写字母,则替换a-zA-ZA-Z.

于 2013-03-02T08:21:37.547 回答
1

您的正则表达式有一个额外的子组。这应该有效:

^\$[A-Z]{5,6}(\,.*)(\,.*)(\,.*)(\,.*)\*[\d\w]{2}$

附带说明一下,这也应该有效,但效率更高,因为它可以消除大量回溯;这 '?' 添加使正则表达式以非贪婪的方式匹配。

^\$[A-Z]{5,6}(\,.*?)(\,.*?)(\,.*?)(\,.*?)\*[\d\w]{2}$

至于您的新编辑,您可以使用以下内容:

^\$[A-Z]{5,6}(\,[^\,]+?)(\,[^\,]+?)(\,[^\,]+?)(\,[^\,]+?)\*[\d\w]{2}$

IE,

  1. 更换 '。' 用 '[^\,]' 匹配除逗号以外的任何字符,而不仅仅是任何字符;和
  2. 将 '*' 替换为 '+' 以避免长度为零的匹配。
于 2013-03-02T08:45:14.580 回答
0

为避免空组,只需替换*+

^\$[A-Z]{5,6}(,.+?)(,.+?)(,.+?)(,.+?)\*\w{2}$

不需要转义逗号和\w包含\d,实际上它相当于[a-zA-Z0-9_]

于 2013-03-02T12:31:09.800 回答