Is there a version of JavaScript's String.indexOf() that allows for regular expressions?
In javascript, is there an equivalent of String.indexOf() that takes a regular expression instead of a string for the first first parameter while still allowing a second parameter ?
I need to do something like
str.indexOf(/[abc]/ , i);
and
str.lastIndexOf(/[abc]/ , i);
While String.search() takes a regexp as a parameter it does not allow me to specify a second argument!
Edit:
This turned out to be harder than I originally thought so I wrote a small test function to test all the provided solutions... it assumes regexIndexOf and regexLastIndexOf have been added to the String object.
function test (str) {
var i = str.length +2;
while (i--) {
if (str.indexOf('a',i) != str.regexIndexOf(/a/,i))
alert (['failed regexIndexOf ' , str,i , str.indexOf('a',i) , str.regexIndexOf(/a/,i)]) ;
if (str.lastIndexOf('a',i) != str.regexLastIndexOf(/a/,i) )
alert (['failed regexLastIndexOf ' , str,i,str.lastIndexOf('a',i) , str.regexLastIndexOf(/a/,i)]) ;
}
}
and I am testing as follow to make sure that at least for one character regexp, the result is the same as if we used indexOf
//Look for the a among the xes
test('xxx');
test('axx');
test('xax');
test('xxa');
test('axa');
test('xaa');
test('aax');
test('aaa');
Combining a few of the approaches already mentioned (the indexOf is obviously rather simple), I think these are the functions that will do the trick:
String.prototype.regexIndexOf = function(regex, startpos) {
var indexOf = this.substring(startpos || 0).search(regex);
return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
}
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;
}
Obviously, modifying the built-in String object would send up red flags for most people, but this may be one time when it is not that big of a deal; simply be aware of it.
UPDATE: Edited regexLastIndexOf()
so that is seems to mimic lastIndexOf()
now. Please let me know if it still fails and under what circumstances.
UPDATE: Passes all tests found on in comments on this page, and my own. Of course, that doesn't mean it's bulletproof. Any feedback appreciated.
Instances of the String
constructor have a .search()
method which accepts a RegExp and returns the index of the first match.
To start the search from a particular position (faking the second parameter of .indexOf()
) you can slice
off the first i
characters:
str.slice(i).search(/re/)
But this will get the index in the shorter string (after the first part was sliced off) so you'll want to then add the length of the chopped off part ( i
) to the returned index if it wasn't -1
. This will give you the index in the original string:
function regexIndexOf(text, re, i) {
var indexInSuffix = text.slice(i).search(re);
return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + i;
}
I have a short version for you. It works well for me!
var match = str.match(/[abc]/gi);
var firstIndex = str.indexOf(match[0]);
var lastIndex = str.lastIndexOf(match[match.length-1]);
And if you want a prototype version:
String.prototype.indexOfRegex = function(regex){
var match = this.match(regex);
return match ? this.indexOf(match[0]) : -1;
}
String.prototype.lastIndexOfRegex = function(regex){
var match = this.match(regex);
return match ? this.lastIndexOf(match[match.length-1]) : -1;
}
EDIT : if you want to add support for fromIndex
String.prototype.indexOfRegex = function(regex, fromIndex){
var str = fromIndex ? this.substring(fromIndex) : this;
var match = str.match(regex);
return match ? str.indexOf(match[0]) + fromIndex : -1;
}
String.prototype.lastIndexOfRegex = function(regex, fromIndex){
var str = fromIndex ? this.substring(0, fromIndex) : this;
var match = str.match(regex);
return match ? str.lastIndexOf(match[match.length-1]) : -1;
}
To use it, as simple as this:
var firstIndex = str.indexOfRegex(/[abc]/gi);
var lastIndex = str.lastIndexOfRegex(/[abc]/gi);
链接地址: http://www.djcxy.com/p/87002.html
上一篇: 你如何只用正则表达式匹配有效的罗马数字?