关于javascript:使用正则表达式验证逗号分隔的数字列表

 2020-10-19 

Validate comma separated list of numbers with regex

这种情况应匹配:

1
2
3
4
5
6
7
8
1.23
1
1,
1.2,4
1.23, 4
1.23, 4,
1, 2.34
1.

这种情况下不应:

1
2
1,,
1.234

因此,逗号后面可以有逗号或点号,零或一空格。 数字可以是整数,也可以是最多两个分数的浮点数。

我做了这个正则表达式,但是它在包含两个以上分数的数字上失败了:
https://regex101.com/r/CLTP2j/75

1
/^(?:\\d+(?:\\.[\\d{1,2}]*)?|\\.[\\d{1,2}]+)(?:,[\\s]?(?:\\d+(?:\\.[\\d{1,2}]*)?|\\.[\\d{1,2}]+))*$/


如果您的目标是确定字符串是否具有正确的格式,而不必使用应用于整个字符串的正则表达式来进行确定,则可以执行以下两个步骤,并使用以下正则表达式:

1
2
r1 = /(?<!,), ?/
r2 = /^\\d+(?:\\.\\d{,2})?$/

这些步骤是:

  • 使用r1将字符串拆分为一个或多个子字符串
  • 确定是否所有子字符串都匹配r2

r1的读法是:"匹配一个逗号,后面最多跟一个空格,不跟逗号。

r2读取,"在字符串的开头匹配一个或多个数字,可以选择在其后跟小数点,然后是0、1或2个数字,然后是字符串的结尾"。

例如,在Ruby中,获得以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
arr =<<~END.split("\
"
)
1.23
1
1,
1.2,4
1.23, 4
1.23, 4,
1, 2.34
1,  2.34
1,,
1.234
END
  #=> ["1.23","1","1,","1.2,4","1.23, 4","1.23, 4,","1, 2.34",
  #   "1,  2.34","1,,","1.234"]

1
2
3
4
5
arr.each do |s|
  a = s.split r1
  result = a.all? { |t| t.match? r2 } ?"(Match)" :"(No match)"
  puts"%-9s: %-14s %s" % [s, a.inspect, result]
end

1
2
3
4
5
6
7
8
9
10
11
12
string     array          match?
---------------------------------
1.23     : ["1.23"]       (Match)
1        : ["1"]          (Match)
1,       : ["1"]          (Match)
1.2,4    : ["1.2","4"]   (Match)
1.23, 4  : ["1.23","4"]  (Match)
1.23, 4, : ["1.23","4"]  (Match)
1, 2.34  : ["1","2.34"]  (Match)
1,  2.34 : ["1"," 2.34"] (No match)
1,,      : ["1",","]     (No match)
1.234    : ["1.234"]      (No match)

这种方法的一个重要优点是,与 r1r2可以分别测试相比,测试要比对整个字符串测试单个正则表达式要容易得多。这种方法将来也可能更容易适应不断变化的需求。


使用以下正则表达式:

1
^\\d+(?:\\.\\d{0,2})?(?:,\\s*\\d+(?:\\.\\d{0,2})?)*,?$

演示版

与其给出我使用的模式的典型冗长(且难以辨认)的完整细分,不如解释一个更简单的要求。假设您要验证大写字母的CSV列表,例如

1
A,B,C

您将使用的模式是:

1
^[A-Z](?:,[A-Z])*,?$

请注意,右边的术语表示允许添加零个或多个逗号,后跟另一个字母。您的要求还允许结尾逗号,因此上述模式也包括逗号。