regex 我如何创建一个正则表达式匹配(p,s)精度和规模像SQL十进制类型?

r6l8ljro  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(360)

精密度(p):小数点左右的总位数
小数位数:小数点右侧的总位数
考虑到目前为止我的以下正则表达式:

^-?[0-9]+(\.[0-9]{1,3})?$
    • ?可选负数
  • [0-9]匹配数字0-9
  • “+”任意位数
  • “(.[0-9]{1,3})?“可选的1-3位小数

示例:

100.95 has a precision of 5 and a scale of 2 (5,2)

我知道如何将总数限制在左边,将总数限制在右边,但不知道如何封装整个值以限制“p,precision”部分,并忽略该计数中存在的句点。* *-**也需要在总计数中忽略。

更新

这似乎起作用了。。

^(?=(\D*\d\D*){0,5}$)-?([0-9]+)?(\.?[0-9]{0,2})?$

blank line matches
0 - match
1 - match
123 - match
123.12 - match
-1 - match
123.122 - no match
ncecgwcz

ncecgwcz1#

您可以在一开始就使用lookahead assertion来验证字符串中的数字是否与您所需的数字相同。

(?=(\D*\d\D*){5}$)

你的整个表情会变成这样:

(?=(\D*\d\D*){5}$)^-?[0-9]+(\.[0-9]{1,3})?$

(我使用shorthand character classes\d(数字)和\D(非数字)是为了简洁和可读性。
它匹配一个数字\d,可能被我们不关心的非数字字符\D*包围,并确保在字符串的$结尾之前匹配{5}的五次。

  • 更新:*

下面是你选定的表达式,经过一些调整简化了:

^(?=(\D*\d\D*){0,5}$)-?\d*(\.\d{0,2})?$

\d[0-9]相同,因此您可以删除一些冗余。

  • ([\d0-9]+)?实际上可能只是\d*(不确定您是否实际使用捕获组,在这种情况下,您应该在它周围留下括号:(\d*)
  • \.?不需要?,因为它后面可以跟0位数字,而且它所在的组已经有了?
  • [\d0-9]{0,2}只能是\d{0,2}
hzbexzde

hzbexzde2#

当使用类型numeric(<precision>[,<scale>])(* 注意 numeric and decimal are synonyms),SQL Server实际上在小数点的左右存储 * 固定数量的空格。
对于下面的类型:numeric(5,2)

  • SQL将最多**2**位分配到小数点的 * 右边
  • SQL将最多5-2 =**3**位分配到小数点的 * 左边 *

这意味着1234.1类似于1234.10,并且无效!

-- Will throw an Arithmetic Overflow Exception
DECLARE @Price AS NUMERIC(5,2) = 1234.1

所以验证这个的正则表达式比这里的一些例子要简单
寻找一个数字\d,你可以得到0到3个{0,3}
然后可选地?,你可以有一个周期\.,然后0到2个数字\d{0,2}
整个正则表达式应该看起来像这样:

\d{0,3}(\.\d{0,2})?

进一步阅读

gg0vcinb

gg0vcinb3#

作为对前面答案的补充,也使用了lookahead。要限制整数的总位数,可以使用(?=(?:-?[\.0-9]{3,8}$)|(?:-?[0-9]{1,7}$))。3表示至少1个精度,需要1个刻度(小数点为3); 7表示具有7精度的整数。
可能有一些次要的边缘情况需要处理。
参见RegEx101

ojsjcaue

ojsjcaue4#

如果你想限制“p,precision”部分(例如,你想限制精度为5),你可以这样做:

^-?(\d{5}|\d{2}(?=\d*\.\d*)[\d.]{3}\d)$

^               # match start of line
-?              # match - literally; zero or one time
(               # capturing group starts
\d{5}|          # match 5 digits (such as, 10095); OR
\d{2}           # match 2 digits; assert at least 2 digits ahead of dot (.)
(?=\d*\.\d*)    # positive lookahead; assert . (dot) can be matched ahead
[\d.]{3}        # match a digit or . (dot) three times
\d              # assert at least one digit at the end
)               # capturing group ends
$               # match end of line

REGEX 101 DEMO

相关问题