JavaScript:搜索正则表达式的字符串,从字符串末尾开始

5

有没有一个JavaScript string函数可以搜索正则表达式,并从结尾开始进行搜索?

如果没有,那么从结尾开始搜索正则表达式的最快和/或最干净的方法是什么?

正则表达式示例:

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

1
JavaScript的String.indexOf()有没有支持正则表达式的版本? - Andreas
7个回答

4
也许这可以更有用且更容易:
str.lastIndexOf(str.match(<your_regex_here>).pop());

这确实适用于OP的RegExp,因此是正确的。但是为了清晰起见,请注意它不能与所有RE一起使用,即具有向前/向后查找的RE。例如:'xhtml html'.match(/(?<=x)html/g)。请参见Andreas在问题上的评论,以获得正确处理此类情况的实现。 - Codesmith
如果 match() 返回 null,这将抛出一个错误。添加条件语句或使用可选链运算符,例如:str.lastIndexOf(str.match(<your_regex_here>)?.pop()); - thdoan

2
也许这对您来说是合适的吗?
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

这需要您正确地格式化正则表达式以精确匹配所需模式并进行全局匹配(如您的问题中所述)。例如,/.*(<\/?([a-z][a-z0-9]*)\b[^>]*>?)/i不适用于此函数。但您所得到的是一个干净且快速的函数。


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);

这是可行的,但我想直接知道正则表达式最后一次出现的索引。如果没有其他更快的方法,那么我可能会把这个作为答案。 - Marl
“result”将返回数组,然后您将需要数组的最后一项。 - Snake Eyes

1
安德烈斯从评论中提供了这个:

Andreas gave this from the comment:

https://dev59.com/w3VC5IYBdhLWcg3wfxQ8#274094

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支持了一些以前缺失的功能,我更新了被接受的答案。 - Marl

0
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;
}

0

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

更新:尝试使用正则表达式。

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

lastIndexOf存在的问题是它的参数不包括正则表达式,只允许字符串。 - Marl
好的,更新后仍然返回使用str.search(/</?([a-z][a-z0-9])\b[^>]>?[\w\W]*$/gi)正则表达式的第一个实例。 - Marl

-1

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

因此,您应该像这样组成您的正则表达式:

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

这将在字符串结束之前找到您的“token”,在那里找不到更多的“token”。“(?:”分组只是使该组不存储,稍微提高性能并节省内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接