【问题标题】:RegEx for extracting scattered numbers in a stringRegEx 用于提取字符串中的分散数字
【发布时间】:2019-10-06 11:08:22
【问题描述】:

来自以下字符串:

Some random text before pattern e-1-e-20-e-3

我想提取“模式前的一些随机文本”和 [1, 20, 3]。

我认为这很简单,并尝试了一些不同的方法,但到目前为止都没有奏效。

这是我的最后一次尝试:

(() => {
  const text = 'Some random text --- e-1-e-20-e-3';

  const re = /(.*)(?:\-?e\-([0-9]{1,2})\-?)+/g;

  const matches = [];
  let match = re.exec(text);
  while (match != null) {
    matches.push(match[1]);
    match = re.exec(text);
  }

  console.log(matches)
})()

前面的返回 ["3"] 我不明白为什么。 我读了: - Getting all subgroups with a regex match - Javascript - Regex access multiple occurrences

我该如何解决这个问题?

编辑:

我变了

我想提取 [1, 20, 3]。

我想提取“模式前的一些随机文本”和 [1, 20, 3]。

我想我的问题是,我可以只使用一个正则表达式来做到这一点,还是必须将搜索分成两部分?

【问题讨论】:

  • \d+ 对于这种情况还不够吗?你能添加规则来选择数字吗?

标签: javascript regex


【解决方案1】:

现在,您在一次迭代中一次匹配整个 e-1-e-20-e-3 子字符串。尝试只匹配 一个 e- 部分,并将捕获的组推送到数组:

const text = 'Some random text --- e-1-e-20-e-3';

const re = /e\-([0-9]{1,2})/g;

const matches = [];
let match = re.exec(text);
while (match != null) {
  matches.push(match[1]);
  match = re.exec(text);
}

console.log(matches)

要同时提取之前的文字,可以(e-\d.*)分割:

const text = 'Some random text before pattern e-1-e-20-e-3';
const [before, after] = text.split(/(e-\d.*)/);
console.log(before.trim());
const re = /e\-([0-9]{1,2})/g;

const matches = [];
let match = re.exec(after);
while (match != null) {
  matches.push(match[1]);
  match = re.exec(after);
}

console.log(matches)

【讨论】:

  • 感谢您的回答。我已经更新了我的问题,因为我需要一些更具体的东西。
  • 查看编辑,由(e-\d.*)分割以将前文本与模式文本分开
【解决方案2】:

\d+ 应该足以提取所有数字。

【讨论】:

    【解决方案3】:

    在这里,我们可以先收集所有字符,然后只传递数字而让其他人失败:

    const regex = /([\s\S].*?)(\d+)/gm;
    const str = `Some random text --- e-1-e-20-e-3`;
    const subst = `$2\n`;
    
    // The substituted value will be contained in the result variable
    const result = str.replace(regex, subst);
    
    console.log('Substitution result: ', result);

    正则表达式

    如果不需要此表达式,可以在 regex101.com 中修改或更改。

    正则表达式电路

    jex.im 也有助于将表达式可视化。


    我们也可以写两个简单的表达式来完成这个任务:

    (.*)(\se-)
    

    ((e-)?(\d+)-?)?
    

    如有必要,我们还可以将它们组合成一个表达式,用逻辑或:

    (.*)(\se-)|((e-)?(\d+)-?)?
    

    const regex = /(.*)(\se-)|((e-)?(\d+)-?)?/gm;
    const str = `Some random text before pattern e-1-e-20-e-3`;
    const subst = `\n$1$5`;
    
    // The substituted value will be contained in the result variable
    const result = str.replace(regex, subst);
    
    console.log('Substitution result: ', result);

    【讨论】:

    • 感谢您的回答。我已经更新了我的问题,因为我需要一些更具体的东西。
    【解决方案4】:

    您实际上可以在没有正则表达式的情况下做到这一点:

    const text = `Some random text --- e-1-e-20-e-3`;
    console.log(text.split("--- e-")[1].split("-e-"));

    如果你真的需要通过正则表达式来做,那么你可以使用:

    (?<=e-)\d+
    

    演示:https://regex101.com/r/WH9b4K/1/

    【讨论】:

    • 感谢您的回答。我已经更新了我的问题,因为我需要一些更具体的东西。在这种情况下,我认为我真的需要正则表达式。
    【解决方案5】:

    您可以选择e-any digit,然后您可以从匹配项中替换e- 以获得所需的结果

    const text = 'Some random text --- e-1-e-20-e-3';
    
    const re = /e-\d{1,2}/g;
    
    console.log(text.match(re).map(value=> value.replace(/e-/g,'')))

    更新:- 我想提取“模式前的一些随机文本”和 [1, 20, 3]。

    const text = 'Some random text before pattern e-1-e-20-e-3'
    
    const [before,after] = text.split(/(e-\d.*)/)
    
    console.log('text value -->',before)
    
    
    const re = /e-\d{1,2}/g;
    
    console.log('after text -->',after.match(re).map(value=> value.replace(/e-/g,'')))

    【讨论】:

    • 感谢您的回答。我已经更新了我的问题,因为我需要一些更具体的东西。
    【解决方案6】:

    您正在重复整个比赛,包括捕获的组。这只会给你捕获组的最后一个值。

    您可以删除外部非捕获组(?:)+

    -?e-([0-9]{1,2})-?
    

    编辑

    您可以获得匹配的第一部分,直到第一次出现 e- 和一个数字,然后将第一部分提取到一个组中。

    例如:

    (() => {
      const text = 'Some random text --- e-1-e-20-e-3';
      const re = /e-([0-9]{1,2})-?/g;
      const matches = [text.replace(/^(.*?)e-\d/, "$1")];
    
      let match = re.exec(text);
      while (match != null) {
        if (match.index === re.lastIndex) {
          re.lastIndex++;
        }
        matches.push(match[1]);
        match = re.exec(text);
      }
    
      console.log(matches)
    })()

    【讨论】:

    • 感谢您的回答。我已经更新了我的问题,因为我需要一些更具体的东西。
    猜你喜欢
    • 2020-06-10
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2021-09-30
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多