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 ' снова изменяет результат?

2 ответов


С String.prototype.match [MDN]:

если регулярное выражение не содержит g флаг, возвращает тот же результат, что и regexp.exec(string).

здесь RegExp.prototype.exec документация [MDN] говорит:

возвращенный массив имеет сопоставленный текст в качестве первого элемента, а затем один элемент для каждой скобки захвата, которая совпала содержащий захваченный текст.

таким образом, как вы ввели группу захвата во втором выражении, первый элемент является целым совпадением, а второй содержит содержимое группы захвата, которая в вашем примере также является целым совпадением.
Первое выражение не имеет группы захвата, поэтому вы возвращаете только совпадение.

обратно в match документы:

если регулярное выражение содержит g флаг, метод возвращает массив, содержащий все совпадения. Если совпадений не было, метод возвращает null.

С g модификатор, возвращаются только совпадения, но не содержимое групп захвата. В вашей струне только одна спичка.


на .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
)

и если вы печатаете массив, он помещает , между значениями.