Some regex pattern is breaking the javascript regex engine -
i wrote following regex: /\d(?!.*\d)|^-?|\d+/g
i think should work way:
\d(?!.*\d) # match last non-digit | # or ^-? # match start of string optional literal '-' character | # or \d+ # match digits
but, doesn't:
var arrtest = '12,345,678.90'.match(/\d(?!.*\d)|^-?|\d+/g); console.log(arrtest); var test = arrtest.join('').replace(/[^\d-]/, '.'); console.log(test);
however, when playing pcre(php)
-flavour online @ regex101. works described.
i don't know if think should work 1 way doesn't work. or if there pattern not allowed in javascript regex-flavour.
js works differently pcre. point js regex engine not handle zero-length matches well, index manually incremented , next character after zero-length match skipped. ^-?
can match empty string, , matches 12,345,678.90
start, skipping 1
.
if have @ string#match
documentation, see each call match
global regex increases regex object's lastindex
after zero-length match found:
- else, global true
a. call [[put]] internal method of rx arguments "lastindex" , 0.
b. let a new array created if expression new array() array standard built-in constructor name.
c. let previouslastindex 0.
d. let n 0.
e. let lastmatch true.
f. repeat, while lastmatch true
i. let result result of calling [[call]] internal method of exec rx this value , argument list containing s.
ii. if result null, set lastmatch false.
iii. else, result not null
1. let thisindex result of calling [[get]] internal method of rx argument "lastindex".
2. if thisindex = previouslastindex then
a. call [[put]] internal method of rx arguments "lastindex" , thisindex+1.
b. set previouslastindex thisindex+1.
so, matching process goes 8a till 8f initializing auxiliary structures, while block entered (repeated until lastmatch true, internal exec command matches empty space @ start of string (8fi -> 8fiii), , result not null, thisindex set lastindex of previous successful match, , match zero-length (basically, thisindex = previouslastindex), previouslastindex set thisindex+1 - which skipping current position after successful zero-length match.
you may use simpler regex inside replace
method , use callback use appropriate replacements:
var res = '-12,345,678.90'.replace(/(\d)(?!.*\d)|^-|\d/g, function($0,$1) { return $1 ? "." : ""; }); console.log(res);
pattern details:
(\d)(?!.*\d)
- non-digit (captured group 1) not followed 0+ chars other newline , non-digit|
- or^-
- hyphen @ string start|
- or\d
- non-digit
note here not have make hyphen @ start optional.
Comments
Post a Comment