Match() возвращает массив с двумя совпадениями, когда я ожидаю одно совпадение
Рассмотрим следующий пример:
<html>
<body>
<script type="text/javascript">
var str="filename.jpg";
var pattOne = new RegExp('\.[^\.]*$');
var pattTwo = new RegExp('(\.[^\.]*$)');
var pattThree = new RegExp('(\.[^\.]*$)', 'g');
document.write(str.match(pattOne));
document.write('<br>');
document.write(str.match(pattTwo));
document.write('<br>');
document.write(str.match(pattThree));
</script>
</body>
</html>
Вот результат:
.jpg
.jpg,.jpg
.jpg
Я ожидаю этого результата:
.jpg
.jpg
.jpg
Почему размещение скобок вокруг регулярного выражения изменяет результат? Почему использование модификатора 'g' снова изменяет результат?
Ответы
Ответ 1
Из String.prototype.match
[MDN]:
Если регулярное выражение не включает флаг g
, возвращает тот же результат, что и regexp.exec(string)
.
Где RegExp.prototype.exec
документация [MDN] говорит:
Возвращаемый массив имеет совпадающий текст в качестве первого элемента, а затем один элемент для каждой скопирующей скобки, совпадающий с содержащим текст.
Итак, когда вы представили группу захвата во втором выражении, первым элементом является целое совпадение, а второе содержит содержимое группы захвата, которое в вашем примере также является полным совпадением.
В первом выражении нет группы захвата, поэтому вы возвращаете только совпадение.
Вернуться к документации match
:
Если регулярное выражение включает флаг g
, метод возвращает массив, содержащий все совпадения. Если совпадений не было, метод возвращает null
.
С модификатором g
возвращаются только совпадения, но не содержание групп захвата. В вашей строке есть только одно совпадение.
Ответ 2
Функция .match()
возвращает массив. document.write()
напечатал массив как строку.
Когда вы захватили группу в строке, она создает такой массив:
Array(
[0] => 'the complete matched string',
[1] => 'the first captured group',
[2] => 'the second captured group',
[.] => '...'
)
Итак, с вашим регулярным выражением это будет:
Array(
[0] => '.jpg', // You match .jpg of the string
[1] => '.jpg' // You captured the .jpg match
)
И если вы печатаете массив, он помещает ,
между значениями.