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:

  1. 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

Popular posts from this blog

python - How to insert QWidgets in the middle of a Layout? -

python - serve multiple gunicorn django instances under nginx ubuntu -

module - Prestashop displayPaymentReturn hook url -