我写了以下正则表达式:/\D(?!.*\D)|^-?|\d+/g
我认为应该这样:
\D(?!.*\D) # match the last non-digit
| # or
^-? # match the start of the string with optional literal '-' character
| # or
\d+ # match digits
但是,它没有:
var arrTest = '12,345,678.90'.match(/\D(?!.*\D)|^-?|\d+/g);
console.log(arrTest);
var test = arrTest.join('').replace(/[^\d-]/, '.');
console.log(test);
但是,在Regex101在线播放 PCRE(php)
- 味道时。它像我描述的那样工作。
我不知道我是否认为它应该以某种方式起作用。或者如果javascript regex-flavor中有一些模式不允许。
答案 0 :(得分:3)
JS与PCRE的工作方式不同。关键是JS正则表达式引擎不能很好地处理零长度匹配,索引只是手动递增,并且跳过零长度匹配后的下一个字符。 ^-?
可以匹配空字符串,并且匹配12,345,678.90
开头,跳过1
。
如果我们查看String#match
documentation,我们会看到每次使用全局正则表达式调用match
都会在零长度<之后增加正则表达式对象的lastIndex
找到/ em>匹配:
- 否则,全球 true
醇>
一个。使用参数“ lastIndex ”和0来调用rx的[[Put]]内部方法 湾设A是一个新的数组,就像表达式 new Array()一样,其中数组是具有该名称的标准内置构造函数。
C。设 previousLastIndex 为0 d。设 n 为0 即让 lastMatch 为 true 。
F。重复,而 lastMatch 是 true
一世。设结果是使用 rx 调用 exec 的[[Call]]内部方法的结果 this 包含 S 的值和参数列表 II。如果结果 null ,则将 lastMatch 设置为 false 。
III。否则,结果不是 null
1.让 thisIndex 成为使用参数“ lastIndex ”调用 rx 的[[Get]]内部方法的结果。
2.如果 thisIndex = previousLastIndex 则为
一个。使用参数“ lastIndex ”和 thisIndex + 1 调用 rx 的[[Put]]内部方法。
湾将 previousLastIndex 设置为 thisIndex +1。
因此,匹配过程从 8a 到 8f 初始化辅助结构,然后输入while块(重复直到 lastMatch 为 true ,内部 exec 命令匹配字符串开头的空白区域( 8fi - &gt; 8fiii ),并且由于结果不是 null , thisIndex 被设置为上一次成功匹配的 lastIndex ,并且匹配为零 - 长度(基本上, thisIndex = previousLastIndex ), previousLastIndex 设置为 thisIndex + 1 - 在成功进行零长度匹配后跳过当前位置。
您实际上可以在replace
方法中使用更简单的正则表达式,并使用回调来使用适当的替换:
var res = '-12,345,678.90'.replace(/(\D)(?!.*\D)|^-|\D/g, function($0,$1) {
return $1 ? "." : "";
});
console.log(res);
模式详情:
(\D)(?!.*\D)
- 非数字(捕获到第1组),除了换行符和其他非数字之外没有跟随0 +字符|
- 或^-
- 字符串开头的连字符|
- 或\D
- 非数字请注意,在这里你甚至不必在开始时选择连字符。
答案 1 :(得分:2)
你可以重新安排你的交替模式,并在JS中使用它来使它工作:
var arrTest = '12,345,678.90'.match(/\D(?!.*\D)|\d+|^-?/g);
console.log(arrTest);
var test = arrTest.join('').replace(/\D/, '.');
console.log(test);
//=> 12345678.90
&#13;
这是Javascript和PHP(PCRE)正则表达式行为之间的区别。
在Javascript中:
'12345'.match(/^|.+/gm)
//=> ["", "2345"]
在PHP中:
preg_match_all('/^|.+/m', '12345', $m);
print_r($m);
Array
(
[0] => Array
(
[0] =>
[1] => 12345
)
)
因此,当您在Javascript中匹配^
时,正则表达式引擎会向前移动一个位置,而在交替|
之后的任何内容都会从输入中的第二个位置开始匹配。