我试图创建一个正则表达式,它可以匹配括号内的数字,例如:
(1.000.000,00) //match
(1.000,00) //match
(100,00) //match
(10) //match
(1) //match
(2.000.000,00 //dont't match
(2.000,00 //dont't match
(200,00 //dont't match
(20 //dont't match
(2 //dont't match
3.000.000,00) //dont't match
3.000,00) //dont't match
300,00) //dont't match
30) //dont't match
3) //dont't match
4.000.000,00 //should match
4.000,00 //should match
400,00 //should match
40 //should match
4 //should match
我只需要匹配数字(不管是否括号中),但只有当它们有所有括号(2)或无(0)
现在这就是我想出来的:\((\d+[\.,]?)+\d*\)
,它匹配--匹配,不匹配--不匹配,但也应该匹配--应该匹配。
我添加了javascript
标记,因为我在js中使用这个regex,而不是在js regex构造函数中使用所有regex令牌。
我还发了一个regex101 链接
发布于 2021-11-29 09:24:07
如果受支持,您可以使用负回头看来匹配带括号或不带括号:
\(\d+(?:[.,]\d+)*\)|(?<!\S)\d+(?:[.,]\d+)*(?!\S)
\(
匹配(
\d+(?:[.,]\d+)*
匹配1+数字,并可选择重复匹配.
或,
和再匹配1+数字。\)
匹配)
|
或(?<!\S)
负查找,向左断言一个单词边界\d+(?:[.,]\d+)*
匹配1+数字,并可选择重复匹配.
或,
和再匹配1+数字。(?!\S)
负前瞻,向右断言空格边界另一个选项可以是匹配两边的可选括号,并且只保留具有开括号和结束括号或无括号的括号。
const regex = /\(?\d+(?:[.,]?\d+)*\)?/
const strings = ["(1.000.000,00)", "(1.000,00)", "(100,00)", "(10)", "(1)", "(2.000.000,00", "(2.000,00", "(200,00", "(20", "(2", "3.000.000,00)", "3.000,00)", "300,00)", "30)", "3)", "4.000.000,00", "4.000,00", "400,00", "40", "4"];
strings.forEach(s => {
const m = s.match(regex);
const firstChar = s.charAt(0);
const lastChar = s.charAt(s.length - 1);
if (
m &&
(firstChar !== '(' && lastChar !== ')') ||
firstChar === '(' && lastChar === ')'
) {
console.log(s)
}
});
发布于 2021-11-29 09:29:22
编辑:这个坏了。它将匹配类似于(7 )的数字,因为它只匹配数字,并忽略了这种情况下的括号。
保存在这里供将来参考。
在多次传递中进行正则化通常比较容易,但如下所示:
/(\((\d+[\.,]?)+\d*\))|(\d+[\.,]?\d*)/gm
您可以在https://regex101.com/上测试它。通常,最好在多次传递中处理某些内容,因为您可以看到正则表达式变得更加不可读。我将正则表达式拆分为两个正则表达式:一个需要括号,另一个不需要括号,然后将它们与or操作符组合在一起。请注意,这个正则表达式将允许像“123.5.7”这样的东西作为一个数字,并且捕获组将是令人讨厌的。
发布于 2021-11-29 09:44:48
如果您不想重复部分匹配的数字(在本例中是短的,所以可能需要一个干规则的例外),您可以使用\(?((\d+[\.,]?)+\d*)\)?(?<=\(\1\)|(^|[^(\d.,])\1(?=($|[^\d.,)])))
。
https://stackoverflow.com/questions/70158635
复制