【问题标题】:Javascript regex error possibly needs look-back type functionality?Javascript 正则表达式错误可能需要回溯类型功能?
【发布时间】:2015-11-05 14:34:02
【问题描述】:

我正在尝试在 Javascript 学习网站上完成一个练习。

说明是:

  • 输入:单词字符串,其中一些单词可能包含井号/井号#。

  • 输出:以井号/井号 # 为前缀但不包含井号/井号 # 的字符串数组。

  • 单独的磅号不算数,例如:字符串“#”将返回一个空数组。

  • 如果一个词前面有多个主题标签,则只计算最后一个主题标签(例如,“##alot”将返回 [“alot”])
  • 标签不能位于单词的中间(例如,“in#line hashtag”返回一个空数组)
  • 标签必须在字母字符之前(例如“#120398”或“#?”无效)

我的努力是这样的:

function getHashtags(post) {
  return /#(\w+)/.exec(post)
}

但结果是这样的:

String Input: Hello #world
Outpu t: [ '#world', 'world', index: 6, input: 'Hello #world' ]

String Input: #lol #sorryNotSorry #heya #coolbeans
Output: [ '#lol','lol', index: 0, input: '#lol #sorryNotSorry #heya #coolbeans']

String Input: # # # #
Output: null

String Input: this is an in#line hash
Output: [ '#line', 'line', index: 13, input: 'this is an in#line hash' ]

String Input: too ##many tags
Output: [ '#many', 'many', index: 5, input: 'too ##many tags' ]

String Input: invalid chars #$? #;wha
Output: null

String Input: "" //empty string
null

String Input: #blue#red#yellow#green
Output:[ '#blue', 'blue', index: 0, input: '#blue#red#yellow#green' ]

我认为我需要回溯功能,但我知道 Javascript 不支持它并且我无法找到解决方法!有人可以帮忙吗?

【问题讨论】:

    标签: javascript arrays regex string


    【解决方案1】:

    您实际上(几乎)正确地做到了。当您使用exec 时,它只返回第一组结果。如果您继续调用exec(假设您使用全局标志g),它将开始返回下一个匹配项。这个例子取自 Mozilla 的网站:

    var myRe = /ab*/g;
    var str = 'abbcdefabh';
    var myArray;
    while ((myArray = myRe.exec(str)) !== null) {
      var msg = 'Found ' + myArray[0] + '. ';
      msg += 'Next match starts at ' + myRe.lastIndex;
      console.log(msg);
    }
    

    Exec

    我是否可以补充一点,每个人都可以从这个问题的提问中学到什么。很好地展示了您为解决问题所做的工作。我什至会告诉你如何实现它。

    function getHashtags(post)
    {
        regex = /#(\w+)/g;
        arr = [];
    
        while((results = regex.exec(post)) !== null)
        {
            arr.push(results[1]);
        }
    
        return arr;
    }
    

    【讨论】:

    • @stribizhev & iismathwizard 非常感谢您的帮助,我使用了您的两种方法function getHashtags(post) { regex = /\B#+([a-z]\w*)/gi; ///#(\w+)/g; arr = []; while((results = regex.exec(post)) !== null) { arr.push(results[1]); } console.log(arr) return arr; } 的混合,它通过了大多数情况但卡在#blue#red#yellow#与 ['blue'] 匹配的绿色 -
    【解决方案2】:

    标签不能在单词的中间(例如“in#line hashtag”返回一个空数组)

    -- 使用不允许单词字符出现在# 之前的非单词边界\B。此外,若要在 # 位于主题标签中间时排除匹配项,请添加一个不跟在 # 后面的单词边界:(?!#)\b

    标签必须在字母字符之前(例如“#120398”或“#?”无效)

    -- 在# 之后使用[a-zA-Z],然后您可以使用\w。或者[a-z],如果您打算添加/i 修饰符。

    所以,使用

    /\B#+([a-z]\w*(?!#)\b)/gi
    

    demo

    这将涵盖基本的基于拉丁脚本的主题标签提取。

    function getHashtags(post) {
      var re = /\B#+([a-z]\w*(?!#)\b)/gi;
      arr = []; 
      while ((m = re.exec(post)) !== null) {
        arr.push(m[1]);
        document.write("Hashtag: " + m[0] + ", name: " + m[1] + "<br/>");
      }
      return arr;
    }
    
    
    var strs = ['##alot', 'Hello #world', '#lol #sorryNotSorry #heya #coolbeans', '# # # #', 'this is an in#line hash', 'too ##many tags', 'invalid chars #$? #;wha', '', '#blue#red#yellow#green'];
    strs.forEach(function (str) {
      console.log(getHashtags(str));
    });

    【讨论】:

    • 没有必要更新lastIndex,因为调用exec 会帮您完成
    • 并不总是,有时,当您删除这部分代码时,exec 会冻结。
    • 有什么可以支持这个说法的吗?
    • '如果一个词前面有多个主题标签,则只计算最后一个主题标签(例如,"##alot" 将返回 ["alot"])'。所以正则表达式应该有#+ 而不是#,像这样:var re = /\B#+([a-z]\w*)/gi;
    • @DavidKnipe 我认为这是一个错字,最后一个哈希算数
    猜你喜欢
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 2021-05-19
    • 1970-01-01
    相关资源
    最近更新 更多