Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JavaScript regexp中获取子模式的索引?_Javascript_Regex - Fatal编程技术网

如何在JavaScript regexp中获取子模式的索引?

如何在JavaScript regexp中获取子模式的索引?,javascript,regex,Javascript,Regex,我用JavaScript编写了一个正则表达式,用于在字符串中搜索searchedUrl: var input = '1234 url( test ) 5678'; var searchedUrl = 'test'; var regexpStr = "url\\(\\s*"+searchedUrl+"\\s*\\)"; var regex = new RegExp(regexpStr , 'i'); var match = input.match(regex); console.log(

我用JavaScript编写了一个正则表达式,用于在字符串中搜索
searchedUrl

var input = '1234 url(  test  ) 5678';
var searchedUrl = 'test';

var regexpStr = "url\\(\\s*"+searchedUrl+"\\s*\\)"; 
var regex = new RegExp(regexpStr , 'i');

var match = input.match(regex);
console.log(match); // return an array
输出:

["url(            test  )", index: 5, input: "1234 url(            test  ) 5678"]
现在我想获得
searchedUrl
的位置(在上面的示例中,它是
test
1234url(test)5678中的位置)


我该怎么做呢?

你应该使用.exec,有很多关于子模式匹配的文档,你不需要索引。 在这种情况下,只要提供多一点信息就可以得到更好的答案。我不能怪你;我们被鼓励创建简单的测试用例,并删掉不相关的细节

但有一个重要的问题遗漏了:你打算如何处理该索引。与此同时,我们都在寻找错误的问题。:-)

我有一种感觉,有什么东西不见了;这就是我问你这件事的原因

正如您在评论中所提到的,您希望在输入字符串中找到URL,并以某种方式突出显示它,可以将其包装在
标记或类似标记中:

'1234 url(  <b>test</b>  ) 5678'
这比其他答案中的代码要简单一点,但它们中的任何一个都同样有效。这种方法的工作原理是将正则表达式锚定到字符串的开头(使用
^
),并将所有字符放在URL前面(使用
()
)。组字符串的长度,
match[1]
,是您的索引

切片 一旦知道字符串中
test
的起始索引,就可以使用
.slice()
或其他字符串方法来剪切字符串并插入标记,可能使用类似以下代码:

var input = '1234 url(  test  ) 5678';
var url = 'test';

var regexpStr = "^(.*url\\(\\s*)"+ url +"\\s*\\)"; 
var regex = new RegExp( regexpStr , 'i' );

var match = input.match( regex );
var start = match[1].length;
// Wrap url in <b></b> tag by slicing and pasting strings
var output =
    input.slice( 0, start ) +
    '<b>' + url + '</b>' +
    input.slice( start + url.length );

console.log( output );
这段代码在正则表达式中有三个组,一个用于捕获URL本身,URL前后的组用于捕获其他匹配文本,这样我们就不会丢失它。然后一个简单的
.replace()
就完成了


通过这种方式,您不必担心任何字符串长度或索引。如果找不到URL,代码可以正常工作:它返回的输入字符串保持不变。

据我所知,无法自动获取子匹配的偏移量,您必须使用RegExp的
lastIndex
进行计算,或者由
exec()
返回的匹配对象的
索引
属性。根据您使用的组,您必须添加或减去子匹配前的组长度。但是,这意味着您必须将正则表达式的第一部分或最后一部分分组,直到您希望定位的模式为止

lastIndex
似乎仅在使用
/g/
全局标志时起作用,它将在整个比赛后记录索引。因此,如果您希望使用
lastIndex
,则需要从模式的末尾向后工作

有关
exec()
方法的更多信息,请参阅此处:

以下简要说明了正在运行的解决方案:

var str = '---hello123';
var r = /([a-z]+)([0-9]+)/;
var m = r.exec( str );
alert( m.index + m[1].length ); // will give the position of 123
更新 这将适用于您的问题,具体如下:

var input = '1234 url(  test  ) 5678';
var searchedUrl = 'test';
var regexpStr = "(url\\(\\s*)("+searchedUrl+")\\s*\\)";
var regex = new RegExp(regexpStr , 'i');
var match = regex.exec(input);
然后,要获得子匹配偏移,可以使用:

match.index + match[1].length
match[1]
现在包含
url(
(加两个空格),因为括号分组允许我们告诉内部偏移量

更新2 显然,如果在要定位的实际模式之前,在RegExp中有要分组的模式,事情会变得复杂一些。这只是将每个组长度相加的简单操作

var s = '~- [This may or may not be random|it depends on your perspective] -~';
var r = /(\[)([a-z ]+)(\|)([a-z ]+)(\])/i;
var m = r.exec( s );
要获得
的偏移位置,取决于您的视角,您可以使用:

m.index + m[1].length + m[2].length + m[3].length;

显然,如果您知道RegExp的某些部分永远不会改变长度,那么您可以用硬编码的数值替换它们。但是,最好保持上述
.length
检查,以防您或其他人更改表达式匹配的内容。

JS没有直接的方法来获取子表达式的索引尝试/捕获组。但您可以使用一些技巧来解决此问题。例如:

var reStr = "(url\\(\\s*)" + searchedUrl + "\\s*\\)";
var re = new RegExp(reStr, 'i');

var m = re.exec(input);
if(m){
    var index = m.index + m[1].length;
    console.log("url found at " + index);
}

没有回答问题。他正在寻找子匹配的索引,已经使用
match()
,并且已经显示它包含
index
属性(结果不理想)。我已经研究了你提到的问题,但它没有回答我的问题。你们是对的,我将答案改为使用exec()而不是match()@RobbertvandenBogerd不幸的是,这并没有给潜艇位置either@m.buettner--这是个笑话吗?或者你真的不知道那有多粗鲁。我猜是前者。粗鲁?我认为如果你看到改进的余地,编辑别人的答案肯定是人们应该做的事情(参见,尤其是第二个答案)我认为,你最初的帖子包含了一个非常简洁的解决方案,但答案似乎与问题有点脱节,因为你的例子与OP的输入无关,所以我只是在留下你的文本的同时修改了这个例子,并添加了一些额外的解释,to使答案对OP.@m.buettner更有用是的,添加答案以改进它是好的。不表明原始答案是好的。正如你从我的编辑中所看到的——我最初计划作为第二次迭代——上面的方法是正确的。无论如何,如果代码中有问题,一个小的编辑是好的,但远远不够更礼貌的做法是先通知原始海报,或者让他们进行更改。这有点夸张,因为我只是更改了使用的输入和模式(没有您的解释)并为OP添加了一个小注释和链接,以便阅读捕获的实际情况。如果你计划更新与否,关键是,我不想打扰你,而是改进你的答案,以确保它得到支持和接受。我还可以发布我自己的答案,这在当时更适用于易读的
var reStr = "(url\\(\\s*)" + searchedUrl + "\\s*\\)";
var re = new RegExp(reStr, 'i');

var m = re.exec(input);
if(m){
    var index = m.index + m[1].length;
    console.log("url found at " + index);
}