最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do you access the groups of matchmatchAll like an array? - Stack Overflow

programmeradmin5浏览0评论

Here's what I would like to be able to do:

function convertVersionToNumber(line) {
  const groups = line.matchAll(/^# ([0-9]).([0-9][0-9]).([0-9][0-9])\s*/g);

  return parseInt(groups[1] + groups[2] + groups[3]);
}

convertVersionToNumber("# 1.03.00")

Here's what I would like to be able to do:

function convertVersionToNumber(line) {
  const groups = line.matchAll(/^# ([0-9]).([0-9][0-9]).([0-9][0-9])\s*/g);

  return parseInt(groups[1] + groups[2] + groups[3]);
}

convertVersionToNumber("# 1.03.00")

This doesn't work because groups is an IterableIterator<RegExpMatchArray>, not an array. Array.from doesn't seem to turn it into an array of groups either. Is there an easy way (ideally something that can fit on a single line) that can convert groups into an array?

The API of that IterableIterator<RegExpMatchArray> is a little inconvenient, and I don't know how to skip the first element in a for...of. I mean, I do know how to use both of these, it just seems like it's going to add 4+ lines so I'd like to know if there is a more concise way.

I am using typescript, so if it has any syntactic sugar to do this, I'd be happy to use that.

Share Improve this question edited Oct 5, 2021 at 5:14 Daniel Kaplan asked Sep 1, 2021 at 5:38 Daniel KaplanDaniel Kaplan 67.7k57 gold badges269 silver badges403 bronze badges 3
  • Can you try wrapping the line.matchAll with Array.from – zecuria Commented Sep 1, 2021 at 5:42
  • @zecuria I tried that before I asked the question actually. I don't know what that it is returning, but it doesn't seem to be returning it into an array. – Daniel Kaplan Commented Sep 1, 2021 at 5:44
  • @zecuria thank god for typescript. My IDE tells me it is returning RegExpMatchArray[]. But that can't be added together. – Daniel Kaplan Commented Sep 1, 2021 at 5:46
Add a ment  | 

2 Answers 2

Reset to default 4

1) matchAll will return an Iterator object Iterator [RegExp String Iterator]

result will contain an Iterator and when you use the spread operator It will give you all matches. Since it contains only one match so It contains a single element only.

[ '# 1.03.00', '1', '03', '00', index: 0, input: '# 1.03.00', groups: undefined ]

Finally, we used a spread operator to get all value and wrap it in an array

[...result]

function convertVersionToNumber(line) {
  const result = line.matchAll(/^# ([0-9]).([0-9][0-9]).([0-9][0-9])\s*/g);
  const groups = [...result][0];
  return parseInt(groups[1] + groups[2] + groups[3]);
}

console.log(convertVersionToNumber("# 1.03.00"));

Since you are using regex i.e /^# ([0-9]).([0-9][0-9]).([0-9][0-9])\s*/

2) If there are multiple matches then yon can spread results in an array and then use for..of to loop over matches

function convertVersionToNumber(line) {
  const iterator = line.matchAll(/# ([0-9]).([0-9][0-9]).([0-9][0-9])\s*/g);
  const results = [...iterator];
  for (let arr of results) {
    const [match, g1, g2, g3] = arr;
    console.log(match, g1, g2, g3);
  }
}

convertVersionToNumber("# 1.03.00 # 1.03.00");

Alternate solution: You can also get the same result using simple match also

function convertVersionToNumber(line) {
  const result = line.match(/\d/g);
  return +result.join("");
}

console.log(convertVersionToNumber("# 1.03.00"));

You do not need .matchAll in this concrete case. You simply want to match a string in a specific format and re-format it by only keeping the three captured substrings.

You may do it with .replace:

function convertVersionToNumber(line) {
  return parseInt(line.replace(/^# (\d)\.(\d{2})\.(\d{2})[\s\S]*/, '$1$2$3'));
}
console.log( convertVersionToNumber("# 1.03.00") );

You may check if the string before replacing is equal to the new string if you need to check if there was a match at all.

Note you need to escape dots to match them as literal chars.

The ^# (\d)\.(\d{2})\.(\d{2})[\s\S]* pattern matches

  • ^ - start of string
  • # - space + #
  • (\d) - Group 1: a digit
  • \. - a dot
  • (\d{2}) - Group 2: two digits
  • \. - a dot
  • (\d{2}) - Group 3: two digits
  • [\s\S]* - the rest of the string (zero or more chars, as many as possible).

The $1$2$3 replacement pattern is the concatenated Group 1, 2 and 3 values.

发布评论

评论列表(0)

  1. 暂无评论