正则表达式以验证模式

时间:2020-06-19 12:47:41

标签: javascript regex reactjs validation material-ui

我是正则表达式的新手,在我的项目中,我允许用户以简写形式和实数形式输入金额,我使用了实质性的UI TextField作为输入。

示例为:

400k - shorthand, 

400.2k - shorthand, 

4m - shorthand,

500. - should work

500000 - full amount

不应允许某些模式用户输入示例,例如:

4.2.k, 

.3k, 

4...k

300.k

我在下面写了正则表达式,但是它允许在数字后输入点。

textValue.match(/^[0-9]*(\.[0-9]{0,2})*([0-9km]{1})$/) && textValue.match(/^[\d]+/)

上面的代码中,第一个正则表达式验证模式,第二个正则表达式强制用户输入Number,因为数量不能以字符串开头,我写了两个单独的正则表达式,因为我不知道如何将它们放在一个正则表达式中,而那些正则表达式则不接受数字后的点。任何人都可以用一个正则表达式来给出完美的正则表达式来验证上述模式吗?

预先感谢

3 个答案:

答案 0 :(得分:2)

有了交替(从来不是最漂亮的),可以像这样:

^\d+([km]|\.|\.\d+[km])?$

请参见Online Demo

  • ^-开始字符串ancor。
  • d+-一个或多个数字。
  • (-打开捕获组(您可以使用非捕获)。
    • [km]-单个字符“ k”或“ m”。
    • |-交替(OR)。
    • \.?-文字点。
    • |-交替(OR)。
    • \.\d+[km]-文字点,后接至少一位数字和字符“ k”或“ m”。
    • )?-关闭捕获组并将其设置为可选
  • $-开始字符串ancor。

enter image description here

答案 1 :(得分:1)

关于您尝试过的模式

请注意,您不需要{1}。字符类[0-9km]匹配一个字符km中的1个或数字0-9。这样,可以匹配的数字可能是0-3,而不是0-2。

为该组使用量词*使得也可以匹配400.25.22.22.22k


您可以使用此模式来验证示例。模式开头的[0-9]+确保必须至少存在一个数字。

如果您想允许500.,可以使用:

^[0-9]+(?:(?:\.[0-9]{1,2})?[km]?|\.)$

说明

  • ^字符串的开头
  • [0-9]+匹配1个以上的数字
  • (?:非捕获组
    • (?:\.[0-9]{1,2})?用2位数字匹配可选的小数部分
    • [km]?匹配可选的km
    • |
    • \.匹配单个点
  • )$字符串结尾

Regex demo

let pattern = /^[0-9]+(?:(?:\.[0-9]{1,2})?[km]?|\.)$/;
[
  "400k",
  "400.2k",
  "4m",
  "500000",
  "500.",
  "300.k",
  "4.2.k",
  ".3k",
  "4...k",
].forEach(s => console.log(s + " --> " + pattern.test(s)));


另一种选择是仅在不直接跟随km的情况下匹配点

^[0-9]+(?:\.(?![km]))?\d*[km]?$

Regex

答案 2 :(得分:1)

您可以尝试:

^\d+\.?(?:\d+)?[KkMm]?(?<!\.[KkMm])$

上述正则表达式的解释:

^, $ -分别匹配行的开始和结束。

\d+ -匹配数字1次或更多次。

\.? -表示.出现0或1。

[KkMm]? -匹配提到的字符类中的可选字符。

(?<!\.[KkMm]) -表示.之后不匹配字符的否定后视。

您可以在here.中找到上述正则表达式的演示

Pictorial Representation

const regex = /^\d+\.?(?:\d+)?[KkMm]?(?<!\.[KkMm])$/gm;
const str = `400K
4.2.K
4.3K
3.2M
300000
4....K
4K
500.
300.K`;
let m;

while ((m = regex.exec(str)) !== null) {
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`${match}`);
    });
}


使用轮换的第二种有效解决方案:

您可能可以尝试使用此正则表达式以更有效地实现

^\d+(?:\.$|\.\d+)?[KkMm]?$

上述正则表达式的解释:

^, $ -分别匹配行的开始和结束。

\d+ -匹配数字1次或更多次。

(?:\.$|\.\d+)? -代表一个非捕获组;匹配仅后面跟.或十进制数字的数字。

[KkMm]? -匹配提到的字符之一为零或1。

您可以在here.中找到上述正则表达式的演示

Pictorial representation-2

const regex = /^\d+(?:\.$|\.\d+)?[KkMm]?$/gm;
const str = `400K
4.2.K
4.3K
3.2M
300000
4....K
4K
500.
300.K`;
let m;

while ((m = regex.exec(str)) !== null) {
// The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
    console.log(`${match}`);
   });
}

相关问题