如何获得匹配这些字符串的正则表达式

时间:2013-03-02 08:08:55

标签: java regex

我正在尝试为通过TCP / IP套接字显示的String显示正常表达。

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

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

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

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

我预计它会匹配,但事实并非如此。即使我已阅读Java doc,我仍然不熟悉正则表达式。请帮助我获得正确的正则表达式。

被修改

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

^\$[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)。 我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

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

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

数据部分与此表达式匹配:

(,[^,*]*)*

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

如果支票金额不允许使用小写字母,请将a-zA-Z替换为A-Z

答案 1 :(得分:1)

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

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

另一方面,这也应该有效,但效率更高,因为它可以消除大量的反向跟踪; '?'添加使得正则表达式以非贪婪的方式匹配。

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

关于您的新修改,您可以使用以下内容:

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

即,

  1. 替换'。'使用'[^ \,]'来匹配除逗号之外的任何字符,而不仅仅是任何字符;和
  2. 将'*'替换为'+'以避免长度为零的匹配。

答案 2 :(得分:0)

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

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

没有必要逃避逗号,\w包括\d,实际上它等同于[a-zA-Z0-9_]