【问题标题】:Javascript: String search for regex, starting at the end of the stringJavascript:正则表达式的字符串搜索,从字符串的末尾开始
【发布时间】:2013-10-27 01:56:17
【问题描述】:

是否有一个 javascript string 函数,search 是一个正则表达式,它会在最后开始搜索?

如果不是,从末尾开始搜索正则表达式索引的最快和/或最简洁的方法是什么?

正则表达式示例:

/<\/?([a-z][a-z0-9]*)\b[^>]*>?/gi

【问题讨论】:

标签: javascript regex


【解决方案1】:

您可以创建一个反向函数,如:

function reverse (s) {
  var o = '';
  for (var i = s.length - 1; i >= 0; i--)
    o += s[i];
  return o;
}

然后使用

var yourString = reverse("Your string goes here");
var regex = new Regex(your_expression);
var result = yourString.match(regex);

另一个想法:如果你想按单词倒序搜索,那么

function reverseWord(s) {
   var o = '';
   var split = s.split(' ');

  for (var i = split.length - 1; i >= 0; i--)
    o += split[i] + ' ';
  return o;
}

var yourString = reverseWord("Your string goes here");
var regex = new Regex(your_expression);
var result = yourString.match(regex);

【讨论】:

  • 这是可行的,但我想直接知道最后一次出现的正则表达式的索引。如果没有其他更快的方法,那么我可能会将此作为答案
  • result 将返回数组,之后您需要数组的最后一项。
【解决方案2】:

这取决于您究竟想要搜索什么。您可以使用string.lastIndexOf 或在正则表达式中使用$(字符串结尾)。

更新: 试试正则表达式

/<\/?([a-z][a-z0-9]*)\b[^>]*>?[\w\W]*$/gi

【讨论】:

  • lastIndexOf 的问题是参数中不包含正则表达式,它只允许字符串
  • 好吧,更新后仍然使用 str.search(/]* 返回正则表达式的第一个实例>?[\w\W]*$/gi);
【解决方案3】:

假设你正在寻找一个字符串'token',那么你需要'token'的位置,直到字符串末尾没有其他'token'。

所以你应该像这样编写你的正则表达式:

$token = 'token';
$re = "/(?:$token)[^(?:$token)]*$/";

这将找到您的“令牌”,直到字符串结束才能找到进一步的“令牌”。 "(?:" 分组只是使组不存储,稍微加快性能并节省内存。

【讨论】:

    【解决方案4】:

    Andreas 从评论中给出了这个:

    https://stackoverflow.com/a/274094/402037

    String.prototype.regexLastIndexOf = function(regex, startpos) {
        regex = (regex.global) ? regex : new RegExp(regex.source, "g" + (regex.ignoreCase ? "i" : "") + (regex.multiLine ? "m" : ""));
        if(typeof (startpos) == "undefined") {
            startpos = this.length;
        } else if(startpos < 0) {
            startpos = 0;
        }
        var stringToWorkWith = this.substring(0, startpos + 1);
        var lastIndexOf = -1;
        var nextStop = 0;
        while((result = regex.exec(stringToWorkWith)) != null) {
            lastIndexOf = result.index;
            regex.lastIndex = ++nextStop;
        }
        return lastIndexOf;
    }
    

    它提供了我需要的功能,我测试了我的正则表达式,它是成功的。所以我会用这个

    【讨论】:

    • 这是几年前的答案,但由于 javascript 现在支持一些以前缺少的功能,所以我更新了接受的答案。
    【解决方案5】:
    var m = text.match(/.*(<\/?([a-z][a-z0-9]*)\b[^>]*>?)/i);
    if (m) {
        textFound = m[1];
        position = text.lastIndexOf(textFound);
    }
    

    使用 .* 跳过尽可能多的文本,捕获找到的文本并使用 lastIndexOf 进行搜索

    编辑:

    好吧,如果找到文本,则无需使用 lastIndexOf 进行搜索。 m[0] 包含全部重合(包括所有初始填充),m[1] 包含搜索到的文本。所以找到的文本的位置是 m[0].length - m[1].length

    var m = text.match(/.*(<\/?([a-z][a-z0-9]*)\b[^>]*>?)/i);
    if (m) {
        textFound = m[1];
        position = m[0].length - m[1].length;
    }
    

    【讨论】:

      【解决方案6】:

      也许这样的东西适合你?

      Javascript

      function lastIndexOfRx(string, regex) {
          var match = string.match(regex);
      
          return  match ? string.lastIndexOf(match.slice(-1)) : -1;
      }
      
      var rx = /<\/?([a-z][a-z0-9]*)\b[^>]*>?/gi;
      
      console.log(lastIndexOfRx("", rx));
      console.log(lastIndexOfRx("<i>it</i><b>bo</b>", rx));
      

      jsFiddle

      仅出于兴趣,此功能与您选择使用的功能。 jsperf

      这要求您正确格式化您的正则表达式以完全匹配您想要的全局模式(如您的问题中给出的),例如/.*(&lt;\/?([a-z][a-z0-9]*)\b[^&gt;]*&gt;?)/i 将不适用于此功能。但是你得到的是一个干净而快速的功能。

      【讨论】:

        【解决方案7】:

        也许这会更有用且更容易:

        str.lastIndexOf(str.match(<your_regex_here>).pop());
        

        【讨论】:

        • 这确实适用于 OP 的 RegExp;所以这是正确的。但是,为了清楚起见,请注意它不适用于所有 RE,即具有前瞻/后视功能的 RE。例如'xhtml html'.match(/(?&lt;=x)html/g)。有关正确处理此问题的实现,请参阅 Andreas 对问题的评论。
        猜你喜欢
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-25
        • 1970-01-01
        • 1970-01-01
        • 2018-06-18
        相关资源
        最近更新 更多