Javascript string regex /.*/gm не перехватывает всю строку сразу
Почему JavaScript заменяет строковую функцию?
"aaa\nbbb\nccc".replace(/.*/gm, ".")
// result = "..\n..\n.." but expected was: ".\n.\n."
"aaa\nbbb\nccc".replace(/^.*/gm, ".")
// result = ".\n.\n." -> OK!!!
"aaa\nbbb\nccc".replace(/.*$/gm, ".")
// result = "..\n..\n.." but expected was: ".\n.\n."
Что я делаю не так?
3 ответа
Позвольте мне обратиться к ним в обратном порядке:
Что я делаю не так?
Вы хотите использовать +
не *
, *
означает ноль или более совпадений, что здесь не имеет смысла. +
означает одно или несколько совпадений. Так:
"aaa\nbbb\nccc".replace(/.+/g, ".")
// ".\n.\n."
Также обратите внимание, что если вы не используете ^
или же $
(ваш первый пример), вам не нужно m
модификатор (но это не было проблемой с тем, что вы делали). И тебе не нужно ^
или же $
так как .
не соответствует переводу строки (что я не знал до ответа на этот вопрос).
Почему JavaScript заменяет строковую функцию?
У меня нет земных идей, и я надеюсь, что кто-то еще.
Опять же, используя *
Вы говорите ноль или более совпадений. Таким образом, он соответствует всем соответствующим символам, заменяя их первой точкой; тогда это соответствует нулевым символам, заменяя их одной точкой. Результат: две точки.
Доказательство:
"aaa\nbbb\nccc".replace(/.*/g, function(m) {
console.log("m = '" + m + "'");
});
Выходы:
m = 'ааа' м = '' m = 'bbb' м = '' m = 'ccc' м = ''
Посмотрите на эту инструкцию:
"aaa\nbbb\nccc".replace(/(.*)/gm, ".$1.")
производит:
".aaa...
.bbb...
.ccc..."
.*
Матчи aaa
и заменяет его на .aaa.
затем он соответствует пустой строке и заменяется на ..
,
Такое же поведение при замене .*
от .
Как сказал TJ Crowder, используйте вместо этого: .+
"aaa\nbbb\nccc".replace(/.+/g, ".")
Удивительно, но поведение ожидается. Пустая строка удовлетворяет регулярному выражению .*
:
/.*/.test("");
// true
/.*/.exec("");
// [""]
Чтобы понять, что происходит, обратите внимание на вывод:
"aaa\nbbb\nccc".match(/.*/g);
// ["aaa", "", "bbb", "", "ccc", ""]
// m flag dropped because ^ and $ are not used
Помня, что .
не совпадает \n
Матч-замена производится следующим образом:
.*
Матчиaaa
- потому что
g
флаг, строка послеaaa
в поисках совпадения.*
Матчи""
- строка нулевой длины послеaaa
и раньше\n
.*
не совпадает\n
.*
Матчиbbb
.*
Матчи""
- строка нулевой длины послеbbb
и раньше\n
И так далее. Просто используйте .+
чтобы избежать совпадения пустых строк.