क्या जावास्क्रिप्ट का String.indexOf () संस्करण है जो नियमित अभिव्यक्ति की अनुमति देता है?


214

जावास्क्रिप्ट में, क्या String.indexOf () के बराबर है जो पहले पैरामीटर के लिए एक स्ट्रिंग के बजाय एक नियमित अभिव्यक्ति लेता है जबकि अभी भी एक दूसरे पैरामीटर की अनुमति है?

मुझे कुछ ऐसा करने की जरूरत है

str.indexOf(/[abc]/ , i);

तथा

str.lastIndexOf(/[abc]/ , i);

जबकि String.search () एक पैरामीटर के रूप में एक regexp लेता है यह मुझे एक दूसरे तर्क को निर्दिष्ट करने की अनुमति नहीं देता है!

संपादित करें:
यह मूल रूप से मैंने जितना सोचा था उससे अधिक कठिन हो गया था इसलिए मैंने सभी प्रदान किए गए समाधानों का परीक्षण करने के लिए एक छोटा परीक्षण फ़ंक्शन लिखा ... यह मानता है कि regexIndexOf और regexLastIndexOf को स्ट्रिंग ऑब्जेक्ट में जोड़ा गया है।

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

और मैं यह सुनिश्चित करने के लिए परीक्षण कर रहा हूं कि कम से कम एक वर्ण regexp के लिए, परिणाम वैसा ही है जैसे कि हमने indexOf का उपयोग किया है

// xes
परीक्षण ('xxx') के बीच में देखें;
परीक्षण ( 'axx');
परीक्षण ( 'XAX');
परीक्षण ( 'xxa');
परीक्षण ( 'एक्सा');
परीक्षण ( 'XAA');
परीक्षण ( 'AAX');
परीक्षण ( 'एएए');


|अंदर [ ]शाब्दिक चरित्र से मेल खाता है |। आप शायद मतलब था [abc]
मार्कस जार्डेरोट 22

हाँ धन्यवाद आप सही हैं, मैं इसे ठीक कर दूंगा लेकिन regexp अपने आप में अप्रासंगिक है ...
Pat

मेरे जवाब पैट अद्यतन, किसी भी प्रतिक्रिया के लिए धन्यवाद।
जेसन बंटिंग

मैंने पाया कि एक सरल और प्रभावी तरीका सिर्फ string.match (/ [AZ] /) का उपयोग करना है। अगर कोई ज्यादा है, विधि रिटर्न अशक्त, अन्यथा आप एक वस्तु हो, आप मैच (/ [AZ] /) कर सकते हैं सूचकांक पहली राजधानी पत्र के सूचकांक प्राप्त करने के लिए।
Syler

जवाबों:


129

पहले से बताए गए कुछ दृष्टिकोणों को मिलाकर (इंडेक्सऑफ स्पष्ट रूप से सरल है), मुझे लगता है कि ये ऐसे कार्य हैं जो चाल करेंगे:

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

जाहिर है, बिल्ट-इन स्ट्रिंग ऑब्जेक्ट को संशोधित करना ज्यादातर लोगों के लिए लाल झंडे भेजना होगा, लेकिन यह एक समय हो सकता है जब यह एक सौदे का बड़ा नहीं है; बस इसके बारे में पता होना चाहिए।


अद्यतन: संपादित किया गया है regexLastIndexOf()ताकि lastIndexOf()अब नकल हो सके। कृपया मुझे बताएं कि क्या यह अभी भी विफल है और किन परिस्थितियों में है।


अद्यतन: इस पृष्ठ पर टिप्पणियों में पाए गए सभी परीक्षण और मेरे अपने पास। बेशक, इसका मतलब यह नहीं है कि यह बुलेटप्रूफ है। किसी भी प्रतिक्रिया की सराहना की।


आपका regexLastIndexOfकेवल अंतिम गैर-अतिव्यापी मिलान का सूचकांक वापस आ जाएगा ।
मार्कस जार्डेरोट

क्षमा करें, एक विशाल रेगेक्स आदमी नहीं - क्या आप मुझे एक उदाहरण दे सकते हैं जो मुझे विफल कर देगा? मैं अधिक जानने में सक्षम होने की सराहना करता हूं, लेकिन आपकी प्रतिक्रिया किसी को अज्ञानी के रूप में मदद नहीं करती है जैसा कि मैं हूं। :)
जेसन बंटिंग

जेसन I ने प्रश्न में परीक्षण करने के लिए कुछ फ़ंक्शन जोड़ा। यह विफल हो रहा है (अन्य परीक्षणों के बीच) निम्नलिखित 'axx'.lastIndexOf (' a ', 2)! =' axx'.regexLastIndexOf (/ a /, 2)
Pat

2
मुझे लगता है कि इसके regex.lastIndex = result.index + 1;बजाय इसका उपयोग करना अधिक कुशल है regex.lastIndex = ++nextStop;। यह किसी भी परिणाम को खोए बिना बहुत तेजी से अगले मैच के लिए आगे बढ़ेगा।
गेद्रोक्स

1
यदि आप इसे npm से खींचना पसंद करते हैं, तो ये दो उपयोग कार्य अब NPM पर हैं: npmjs.com/package/index-of-regex
Capaj

185

Stringकंस्ट्रक्टर के उदाहरणों में एक .search()विधि है जो एक RegExp को स्वीकार करता है और पहले मैच का सूचकांक देता है।

किसी विशेष स्थिति से खोज शुरू करने के लिए (दूसरे पैरामीटर को रोकना .indexOf()) आप sliceपहले iवर्णों को बंद कर सकते हैं :

str.slice(i).search(/re/)

लेकिन यह छोटे स्ट्रिंग में इंडेक्स प्राप्त करेगा (पहले भाग को बंद कर दिया गया था) के बाद से आप कटे हुए भाग की लंबाई ( i) को लौटाए गए इंडेक्स में जोड़ सकते हैं यदि यह नहीं था -1। यह आपको मूल स्ट्रिंग में सूचकांक देगा:

function regexIndexOf(text, re, i) {
    var indexInSuffix = text.slice(i).search(re);
    return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + i;
}

1
सवाल से: जबकि String.search () एक पैरामीटर के रूप में एक regexp लेता है यह मुझे एक दूसरे तर्क को निर्दिष्ट करने की अनुमति नहीं देता है!
पैट

14
str.substr (i) .search (/ re /)
Glenn

6
महान समाधान, हालांकि आउटपुट थोड़ा अलग है। indexOf शुरुआत से एक नंबर लौटाएगा (ऑफसेट की परवाह किए बिना), जबकि यह ऑफसेट से स्थिति वापस कर देगा। तो, समानता के लिए, आप कुछ इस तरह चाहते हैं:function regexIndexOf(text, offset) { var initial = text.substr(offset).search(/re/); if(initial >= 0) { initial += offset; } return initial; }
gkoberger

39

मेरे पास आपके लिए एक छोटा संस्करण है। ये मेरे लिए अच्छी तरह से काम करता है!

var match      = str.match(/[abc]/gi);
var firstIndex = str.indexOf(match[0]);
var lastIndex  = str.lastIndexOf(match[match.length-1]);

और यदि आप एक प्रोटोटाइप संस्करण चाहते हैं:

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

संपादित करें : यदि आप 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;
}

इसका उपयोग करने के लिए, इस रूप में सरल:

var firstIndex = str.indexOfRegex(/[abc]/gi);
var lastIndex  = str.lastIndexOfRegex(/[abc]/gi);

यह वास्तव में एक अच्छी चाल है। WOuld महान हो अगर आपने इसे startIndexहमेशा की तरह पैरामीटर लेने के लिए विस्तारित किया है indeoxOfऔर lastIndexOfकरते हैं।
रॉबर्ट कोरिटनिक

@RobertKoritnik - मैंने समर्थन startIndex(या fromIndex) के लिए अपना उत्तर संपादित किया । आशा करता हूँ की ये काम करेगा!
शाम

lastIndexOfRegexfromIndexपरिणाम के मूल्य को वापस जोड़ना चाहिए ।
पीटर

आपका एल्गोरिथ्म निम्नलिखित परिदृश्य में टूट जाएगा: "aRomeo Romeo".indexOfRegex(new RegExp("\\bromeo", 'gi'));परिणाम 1 होगा जब यह 7 होना चाहिए, क्योंकि indexOf पहली बार "रोमियो" दिखाई देगा, भले ही यह किसी शब्द की शुरुआत में हो या न हो।
कोरेलके

13

उपयोग:

str.search(regex)

दस्तावेज़ यहाँ देखें


11
@OZZIE: नहीं, वास्तव में नहीं। यह मूल रूप से ग्लेन का जवाब है (~ 150 अपवोट्स के साथ), इसके अलावा इसमें कोई स्पष्टीकरण नहीं है, जो इसके अलावा अन्य की स्थिति शुरू करने का समर्थन नहीं करता है 0, और पोस्ट किया गया ... सात साल बाद।
ccjmne

7

बेलीपी के जवाब के आधार पर। मुख्य अंतर यह है कि -1यदि पैटर्न का मिलान नहीं किया जा सकता है तो ये विधियाँ वापस लौट आती हैं ।

संपादित करें: जेसन बंटिंग के जवाब के लिए धन्यवाद मुझे एक विचार मिला। .lastIndexरेगेक्स की संपत्ति को संशोधित क्यों नहीं किया गया? हालांकि यह केवल वैश्विक ध्वज के साथ पैटर्न के लिए काम करेगा ( /g)।

संपादित करें: परीक्षण-मामलों को पास करने के लिए अद्यतन किया गया।

String.prototype.regexIndexOf = function(re, startPos) {
    startPos = startPos || 0;

    if (!re.global) {
        var flags = "g" + (re.multiline?"m":"") + (re.ignoreCase?"i":"");
        re = new RegExp(re.source, flags);
    }

    re.lastIndex = startPos;
    var match = re.exec(this);

    if (match) return match.index;
    else return -1;
}

String.prototype.regexLastIndexOf = function(re, startPos) {
    startPos = startPos === undefined ? this.length : startPos;

    if (!re.global) {
        var flags = "g" + (re.multiline?"m":"") + (re.ignoreCase?"i":"");
        re = new RegExp(re.source, flags);
    }

    var lastSuccess = -1;
    for (var pos = 0; pos <= startPos; pos++) {
        re.lastIndex = pos;

        var match = re.exec(this);
        if (!match) break;

        pos = match.index;
        if (pos <= startPos) lastSuccess = pos;
    }

    return lastSuccess;
}

यह अब तक सबसे अधिक आशाजनक लगता है (कुछ साइटैक्स फिक्स के बाद) :-) केवल किनारे की स्थितियों पर कुछ परीक्षण विफल हो रहे हैं। 'Axx'.lastIndexOf (' a ', 0)! =' Axx'.regexLastIndexOf (/ a /, 0) जैसी चीजें ... मैं यह देख रहा हूं कि क्या मैं इन मामलों को ठीक कर सकता हूं
Pat

6

आप रूट का उपयोग कर सकते हैं।

str.substr(i).match(/[abc]/);

O'Reilly द्वारा प्रकाशित सुप्रसिद्ध जावास्क्रिप्ट पुस्तक से: "पदार्थ को ECMAScript द्वारा मानकीकृत नहीं किया गया है और इसलिए इसे हटा दिया गया है।" लेकिन आपको जो मिल रहा है उसके पीछे मूल विचार मुझे पसंद है।
जेसन बंटिंग

1
यह एक गैर-मुद्दा है। यदि आप वास्तव में इसके बारे में चिंतित हैं, तो इसके बजाय String.substring () का उपयोग करें - आपको बस गणित को थोड़ा अलग करना होगा। इसके अलावा, जावास्क्रिप्ट यह मूल भाषा के लिए 100% निहारना नहीं होना चाहिए।
पीटर बेली

यह एक गैर-मुद्दा नहीं है - अगर आपको अपना कोड एक कार्यान्वयन के खिलाफ चल रहा है जो कि रूट को लागू नहीं करता है क्योंकि वे ECMAScript मानकों का पालन करना चाहते हैं, तो आपको समस्याएँ होने वाली हैं। दी गई, प्रतिस्थापन के साथ इसे बदलना इतना कठिन नहीं है, लेकिन इस बात का संज्ञान होना अच्छा है।
जेसन बंटिंग

1
जिस क्षण आपके पास समस्याएं हैं, आपके पास बहुत सरल समाधान हैं। मुझे लगता है कि टिप्पणियां समझदार हैं, लेकिन नीचे का वोट पांडित्यपूर्ण था।
वोरोनोई पोपटो

क्या आप कार्यशील डेमो कोड प्रदान करने के लिए अपना उत्तर संपादित कर सकते हैं?
vsync

5

RexExpउदाहरणों एक है lastIndex (अगर वे वैश्विक हैं) पहले से ही संपत्ति और तो क्या मैं कर रहा हूँ नियमित अभिव्यक्ति को कॉपी, थोड़ा हमारे उद्देश्यों के अनुरूप करने के लिए यह संशोधित करने, है execस्ट्रिंग पर यह आईएनजी और को देखकर lastIndex। यह स्ट्रिंग पर लूपिंग की तुलना में अनिवार्य रूप से तेज होगा। (आपके पास इस बात के पर्याप्त उदाहरण हैं कि इसे स्ट्रिंग प्रोटोटाइप पर कैसे रखा जाए, सही?)

function reIndexOf(reIn, str, startIndex) {
    var re = new RegExp(reIn.source, 'g' + (reIn.ignoreCase ? 'i' : '') + (reIn.multiLine ? 'm' : ''));
    re.lastIndex = startIndex || 0;
    var res = re.exec(str);
    if(!res) return -1;
    return re.lastIndex - res[0].length;
};

function reLastIndexOf(reIn, str, startIndex) {
    var src = /\$$/.test(reIn.source) && !/\\\$$/.test(reIn.source) ? reIn.source : reIn.source + '(?![\\S\\s]*' + reIn.source + ')';
    var re = new RegExp(src, 'g' + (reIn.ignoreCase ? 'i' : '') + (reIn.multiLine ? 'm' : ''));
    re.lastIndex = startIndex || 0;
    var res = re.exec(str);
    if(!res) return -1;
    return re.lastIndex - res[0].length;
};

reIndexOf(/[abc]/, "tommy can eat");  // Returns 6
reIndexOf(/[abc]/, "tommy can eat", 8);  // Returns 11
reLastIndexOf(/[abc]/, "tommy can eat"); // Returns 11

आप RegExp ऑब्जेक्ट पर फ़ंक्शन को भी प्रोटोटाइप कर सकते हैं:

RegExp.prototype.indexOf = function(str, startIndex) {
    var re = new RegExp(this.source, 'g' + (this.ignoreCase ? 'i' : '') + (this.multiLine ? 'm' : ''));
    re.lastIndex = startIndex || 0;
    var res = re.exec(str);
    if(!res) return -1;
    return re.lastIndex - res[0].length;
};

RegExp.prototype.lastIndexOf = function(str, startIndex) {
    var src = /\$$/.test(this.source) && !/\\\$$/.test(this.source) ? this.source : this.source + '(?![\\S\\s]*' + this.source + ')';
    var re = new RegExp(src, 'g' + (this.ignoreCase ? 'i' : '') + (this.multiLine ? 'm' : ''));
    re.lastIndex = startIndex || 0;
    var res = re.exec(str);
    if(!res) return -1;
    return re.lastIndex - res[0].length;
};


/[abc]/.indexOf("tommy can eat");  // Returns 6
/[abc]/.indexOf("tommy can eat", 8);  // Returns 11
/[abc]/.lastIndexOf("tommy can eat"); // Returns 11

मैं कैसे संशोधित कर रहा हूं इसका एक त्वरित विवरण RegExp: क्योंकि indexOfमुझे सिर्फ यह सुनिश्चित करना है कि वैश्विक ध्वज सेट हो। के लिए lastIndexOfकी मैं एक नकारात्मक लुक-आगे उपयोग कर रहा हूँ अंतिम बार होने लगता है, जब तक कि RegExpपहले से ही स्ट्रिंग के अंत में मिलान किया गया था।


4

यह मूल रूप से नहीं है, लेकिन आप निश्चित रूप से इस कार्यक्षमता को जोड़ सकते हैं

<script type="text/javascript">

String.prototype.regexIndexOf = function( pattern, startIndex )
{
    startIndex = startIndex || 0;
    var searchResult = this.substr( startIndex ).search( pattern );
    return ( -1 === searchResult ) ? -1 : searchResult + startIndex;
}

String.prototype.regexLastIndexOf = function( pattern, startIndex )
{
    startIndex = startIndex === undefined ? this.length : startIndex;
    var searchResult = this.substr( 0, startIndex ).reverse().regexIndexOf( pattern, 0 );
    return ( -1 === searchResult ) ? -1 : this.length - ++searchResult;
}

String.prototype.reverse = function()
{
    return this.split('').reverse().join('');
}

// Indexes 0123456789
var str = 'caabbccdda';

alert( [
        str.regexIndexOf( /[cd]/, 4 )
    ,   str.regexLastIndexOf( /[cd]/, 4 )
    ,   str.regexIndexOf( /[yz]/, 4 )
    ,   str.regexLastIndexOf( /[yz]/, 4 )
    ,   str.lastIndexOf( 'd', 4 )
    ,   str.regexLastIndexOf( /d/, 4 )
    ,   str.lastIndexOf( 'd' )
    ,   str.regexLastIndexOf( /d/ )
    ]
);

</script>

मैंने इन विधियों का पूरी तरह से परीक्षण नहीं किया है, लेकिन वे अभी तक काम कर रहे हैं।


उन मामलों को संभालने के लिए अपडेट किया गया
पीटर बेली

हर बार मैं इस जवाब को स्वीकार करने वाला हूं, मुझे एक नया मामला मिलेगा! ये अलग परिणाम देते हैं! चेतावनी ([str.lastIndexOf (/ [d] /, 4), str.regexLastIndexOf (/ [d] /, 4)]);
पैट

ठीक है, निश्चित रूप से वे हैं - str.lastIndexOf पैटर्न पर टाइप ज़बरदस्ती करेंगे - इसे एक स्ट्रिंग में परिवर्तित करना। स्ट्रिंग "/ [d] /" सबसे निश्चित रूप से इनपुट में नहीं मिला है, इसलिए -1 लौटा वास्तव में सटीक है।
पीटर बैली

समझ गया। String.lastIndexOf () पर युक्ति पढ़ने के बाद - मुझे सिर्फ यह गलत समझ में आया कि उस तर्क ने कैसे काम किया। इस नए संस्करण को इसे संभालना चाहिए।
पीटर बेली

कुछ अभी भी सही नहीं है, लेकिन यह देर हो रही है ... मैं एक परीक्षण मामला प्राप्त करने की कोशिश करूंगा, और शायद सुबह इसे ठीक कर दूंगा। अब तक की परेशानी के लिए क्षमा करें।
पैट

2

सभी प्रस्तावित समाधान होने के बाद एक या दूसरे तरीके से मेरे परीक्षण विफल हो जाते हैं, (संपादित करें: मैंने इसे लिखने के बाद परीक्षणों को पास करने के लिए अपडेट किया गया था) मुझे Array.indexOf और Array.lastIndexOf के लिए मोज़िला कार्यान्वयन मिला

मैंने उन का उपयोग अपने स्ट्रिंग St.prototyp.regexIndexOf और String.prototyp.regexLastIndexOf के संस्करण को निम्नानुसार लागू करने के लिए किया:

String.prototype.regexIndexOf = function(elt /*, from*/)
  {
    var arr = this.split('');
    var len = arr.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++) {
      if (from in arr && elt.exec(arr[from]) ) 
        return from;
    }
    return -1;
};

String.prototype.regexLastIndexOf = function(elt /*, from*/)
  {
    var arr = this.split('');
    var len = arr.length;

    var from = Number(arguments[1]);
    if (isNaN(from)) {
      from = len - 1;
    } else {
      from = (from < 0) ? Math.ceil(from) : Math.floor(from);
      if (from < 0)
        from += len;
      else if (from >= len)
        from = len - 1;
    }

    for (; from > -1; from--) {
      if (from in arr && elt.exec(arr[from]) )
        return from;
    }
    return -1;
  };

वे प्रश्न में प्रदान किए गए परीक्षण कार्यों को पास करते हैं।

स्पष्ट रूप से वे केवल तभी काम करते हैं जब नियमित अभिव्यक्ति एक वर्ण से मेल खाती है, लेकिन यह मेरे उद्देश्य के लिए पर्याप्त है क्योंकि मैं इसका उपयोग चीजों के लिए करूंगा जैसे ([abc], \ s, \ W, \ D)

यदि कोई व्यक्ति बेहतर / तेज / क्लीनर / अधिक सामान्य कार्यान्वयन प्रदान करता है तो मैं इस सवाल की निगरानी करता रहूंगा कि यह किसी भी नियमित अभिव्यक्ति पर काम करता है।


वाह, यह कोड का एक लंबा सा है। कृपया मेरे अपडेट किए गए उत्तर की जांच करें और प्रतिक्रिया दें। धन्यवाद।
जेसन बंटिंग

इस कार्यान्वयन का उद्देश्य फ़ायरफ़ॉक्स में lastIndexOf और स्पाइडरमॉन्क जावास्क्रिप्ट इंजन के साथ पूर्ण संगतता है, जिसमें कई ऐसे मामले भी शामिल हैं जो यकीनन किनारे के मामले हैं। [...] वास्तविक दुनिया के अनुप्रयोगों में, आप उन मामलों की अनदेखी करने पर कम जटिल कोड से गणना करने में सक्षम हो सकते हैं।
पैट

फॉर्म मोज़िला पेज :-) मैंने सिर्फ कोड विज्ञापन में बदलाव किया और सभी एज केस छोड़ दिए। चूंकि परीक्षणों में पास होने के लिए अन्य उत्तरों में से कुछ को अपडेट किया गया था, इसलिए मैं उन्हें बेंचमार्क करने की कोशिश करूंगा और सबसे अधिक प्रभावशाली स्वीकार करूंगा। जब मेरे पास इस मुद्दे पर फिर से विचार करने का समय है।
पाट

मैंने अपने समाधान को अपडेट किया और किसी भी प्रतिक्रिया या चीजों की सराहना की जिसके कारण यह विफल हो गया। मैंने छिपकली (उम्मीद से!) द्वारा बताई गई ओवरलैपिंग समस्या को ठीक करने के लिए एक बदलाव किया
जेसन बंटिंग

2

मुझे regexIndexOfएक सरणी के लिए भी एक फ़ंक्शन की आवश्यकता थी, इसलिए मैंने खुद एक प्रोग्राम किया। हालांकि मुझे संदेह है, कि यह अनुकूलित है, लेकिन मुझे लगता है कि इसे ठीक से काम करना चाहिए।

Array.prototype.regexIndexOf = function (regex, startpos = 0) {
    len = this.length;
    for(x = startpos; x < len; x++){
        if(typeof this[x] != 'undefined' && (''+this[x]).match(regex)){
            return x;
        }
    }
    return -1;
}

arr = [];
arr.push(null);
arr.push(NaN);
arr[3] = 7;
arr.push('asdf');
arr.push('qwer');
arr.push(9);
arr.push('...');
console.log(arr);
arr.regexIndexOf(/\d/, 4);

1

कुछ सरल मामलों में, आप विभाजन का उपयोग करके अपनी पीछे की खोज को सरल बना सकते हैं।

function regexlast(string,re){
  var tokens=string.split(re);
  return (tokens.length>1)?(string.length-tokens[tokens.length-1].length):null;
}

यह कुछ गंभीर समस्याएं हैं:

  1. ओवरलैपिंग मैच दिखाई नहीं देंगे
  2. रिटर्न इंडेक्स शुरुआत के बजाय मैच के अंत के लिए है (ठीक है अगर आपका regex एक स्थिर है)

लेकिन उज्जवल पक्ष में यह तरीका कम कोड है। एक निरंतर लंबाई के रेगेक्स के /\s\w/लिए जो ओवरलैप नहीं कर सकता (जैसे शब्द सीमाओं को खोजने के लिए) यह काफी अच्छा है।


0

विरल मिलान वाले डेटा के लिए, string.search का उपयोग करना ब्राउज़रों में सबसे तेज़ है। यह एक पुन: स्लाइस को प्रत्येक पुनरावृत्ति को करता है:

function lastIndexOfSearch(string, regex, index) {
  if(index === 0 || index)
     string = string.slice(0, Math.max(0,index));
  var idx;
  var offset = -1;
  while ((idx = string.search(regex)) !== -1) {
    offset += idx + 1;
    string = string.slice(idx + 1);
  }
  return offset;
}

घने डेटा के लिए मैंने इसे बनाया। यह निष्पादन विधि की तुलना में जटिल है, लेकिन घने डेटा के लिए, यह मेरे द्वारा की गई हर दूसरी विधि की तुलना में 2-10x तेज है, और स्वीकृत समाधान की तुलना में लगभग 100 गुना तेज है। मुख्य बिंदु हैं:

  1. यह कहते हैं कि मैच को सत्यापित करने या जल्दी छोड़ने के लिए एक बार में पारित रेगेक्स पर अमल। मैं यह प्रयोग कर रहा हूँ (= एक समान विधि में), लेकिन IE पर निष्पादन के साथ जाँच नाटकीय रूप से तेज़ है।
  2. यह प्रारूप (') में संशोधित रेगेक्स का निर्माण और कैश करता है। (?! ? र?) '
  3. नए रेगेक्स को निष्पादित किया जाता है और उस निष्पादन से परिणाम, या पहले निष्पादन, वापस कर दिए जाते हैं;

    function lastIndexOfGroupSimple(string, regex, index) {
        if (index === 0 || index) string = string.slice(0, Math.max(0, index + 1));
        regex.lastIndex = 0;
        var lastRegex, index
        flags = 'g' + (regex.multiline ? 'm' : '') + (regex.ignoreCase ? 'i' : ''),
        key = regex.source + '$' + flags,
        match = regex.exec(string);
        if (!match) return -1;
        if (lastIndexOfGroupSimple.cache === undefined) lastIndexOfGroupSimple.cache = {};
        lastRegex = lastIndexOfGroupSimple.cache[key];
        if (!lastRegex)
            lastIndexOfGroupSimple.cache[key] = lastRegex = new RegExp('.*(' + regex.source + ')(?!.*?' + regex.source + ')', flags);
        index = match.index;
        lastRegex.lastIndex = match.index;
        return (match = lastRegex.exec(string)) ? lastRegex.lastIndex - match[1].length : index;
    };

तरीकों के jsPerf

मुझे परीक्षणों के उद्देश्य की समझ नहीं है। जिन स्थितियों में एक रेगेक्स की आवश्यकता होती है, उन्हें इंडेक्सऑफ के लिए कॉल की तुलना करना असंभव है, जो मुझे लगता है कि पहली जगह में विधि बनाने का बिंदु है। पास होने के लिए परीक्षण प्राप्त करने के लिए, यह रेक्सएक्स वेरिएंट को समायोजित करने की तुलना में 'xxx + (?! x)' का उपयोग करने के लिए अधिक समझ में आता है।


0

जेसन बंटिंग का आखिरी इंडेक्स काम नहीं करता है। मेरा इष्टतम नहीं है, लेकिन यह काम करता है।

//Jason Bunting's
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) {
var lastIndex = -1;
var index = this.regexIndexOf( regex );
startpos = startpos === undefined ? this.length : startpos;

while ( index >= 0 && index < startpos )
{
    lastIndex = index;
    index = this.regexIndexOf( regex, index + 1 );
}
return lastIndex;
}

क्या आप एक ऐसा परीक्षण प्रदान कर सकते हैं जो मेरे विफल होने का कारण बनता है? यदि आपने पाया कि यह काम नहीं करता है, तो एक परीक्षण का मामला प्रदान करें, क्यों सिर्फ "यह काम नहीं करता है" कहें और जगह पर एक गैर-इष्टतम समाधान प्रदान करें?
जेसन बंटिंग

हू लड़का। तुम बिलकुल ठीक कह रहे हो। मुझे एक उदाहरण देना चाहिए था। दुर्भाग्य से मैं इस कोड से महीनों पहले चला गया और मुझे पता नहीं है कि असफल मामला क्या था। : - /
एली

अच्छा, ऐसा ही जीवन है। :)
जेसन बंटिंग

0

अभी भी कोई मूल तरीके नहीं हैं जो अनुरोधित कार्य करते हैं।

यहां वह कोड है जो मैं उपयोग कर रहा हूं। यह String.prototype.indexOf और String.prototype.lastIndexOf विधियों के व्यवहार की नकल करता है, लेकिन वे खोज करने के लिए मान का प्रतिनिधित्व करने वाले स्ट्रिंग के अलावा एक RegExp को भी स्वीकार करते हैं।

हां यह एक उत्तर के रूप में काफी लंबा है क्योंकि यह वर्तमान मानकों का यथासंभव अनुसरण करने की कोशिश करता है और निश्चित रूप से इसमें उचित मात्रा में जेएसडीओसी की टिप्पणियां शामिल हैं। हालांकि, एक बार खनन करने के बाद, कोड केवल 2.27k है और एक बार ट्रांसमिशन के लिए gzipped केवल 1023 बाइट्स है।

2 विधियाँ जो इसे जोड़ती हैं String.prototype( Object.defineProperty का उपयोग करके जहाँ उपलब्ध हैं) हैं:

  1. searchOf
  2. searchLastOf

यह उन सभी परीक्षणों को पास करता है जिन्हें ओपी ने पोस्ट किया है और इसके अलावा मैंने दिनचर्या का अपने दैनिक उपयोग में काफी अच्छी तरह से परीक्षण किया है, और यह सुनिश्चित करने का प्रयास किया है कि वे कई वातावरणों में काम करते हैं, लेकिन प्रतिक्रिया / मुद्दों का हमेशा स्वागत है।

/*jslint maxlen:80, browser:true */

/*
 * Properties used by searchOf and searchLastOf implementation.
 */

/*property
    MAX_SAFE_INTEGER, abs, add, apply, call, configurable, defineProperty,
    enumerable, exec, floor, global, hasOwnProperty, ignoreCase, index,
    lastIndex, lastIndexOf, length, max, min, multiline, pow, prototype,
    remove, replace, searchLastOf, searchOf, source, toString, value, writable
*/

/*
 * Properties used in the testing of searchOf and searchLastOf implimentation.
 */

/*property
    appendChild, createTextNode, getElementById, indexOf, lastIndexOf, length,
    searchLastOf, searchOf, unshift
*/

(function () {
    'use strict';

    var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1,
        getNativeFlags = new RegExp('\\/([a-z]*)$', 'i'),
        clipDups = new RegExp('([\\s\\S])(?=[\\s\\S]*\\1)', 'g'),
        pToString = Object.prototype.toString,
        pHasOwn = Object.prototype.hasOwnProperty,
        stringTagRegExp;

    /**
     * Defines a new property directly on an object, or modifies an existing
     * property on an object, and returns the object.
     *
     * @private
     * @function
     * @param {Object} object
     * @param {string} property
     * @param {Object} descriptor
     * @returns {Object}
     * @see https://goo.gl/CZnEqg
     */
    function $defineProperty(object, property, descriptor) {
        if (Object.defineProperty) {
            Object.defineProperty(object, property, descriptor);
        } else {
            object[property] = descriptor.value;
        }

        return object;
    }

    /**
     * Returns true if the operands are strictly equal with no type conversion.
     *
     * @private
     * @function
     * @param {*} a
     * @param {*} b
     * @returns {boolean}
     * @see http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.4
     */
    function $strictEqual(a, b) {
        return a === b;
    }

    /**
     * Returns true if the operand inputArg is undefined.
     *
     * @private
     * @function
     * @param {*} inputArg
     * @returns {boolean}
     */
    function $isUndefined(inputArg) {
        return $strictEqual(typeof inputArg, 'undefined');
    }

    /**
     * Provides a string representation of the supplied object in the form
     * "[object type]", where type is the object type.
     *
     * @private
     * @function
     * @param {*} inputArg The object for which a class string represntation
     *                     is required.
     * @returns {string} A string value of the form "[object type]".
     * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4.2
     */
    function $toStringTag(inputArg) {
        var val;
        if (inputArg === null) {
            val = '[object Null]';
        } else if ($isUndefined(inputArg)) {
            val = '[object Undefined]';
        } else {
            val = pToString.call(inputArg);
        }

        return val;
    }

    /**
     * The string tag representation of a RegExp object.
     *
     * @private
     * @type {string}
     */
    stringTagRegExp = $toStringTag(getNativeFlags);

    /**
     * Returns true if the operand inputArg is a RegExp.
     *
     * @private
     * @function
     * @param {*} inputArg
     * @returns {boolean}
     */
    function $isRegExp(inputArg) {
        return $toStringTag(inputArg) === stringTagRegExp &&
                pHasOwn.call(inputArg, 'ignoreCase') &&
                typeof inputArg.ignoreCase === 'boolean' &&
                pHasOwn.call(inputArg, 'global') &&
                typeof inputArg.global === 'boolean' &&
                pHasOwn.call(inputArg, 'multiline') &&
                typeof inputArg.multiline === 'boolean' &&
                pHasOwn.call(inputArg, 'source') &&
                typeof inputArg.source === 'string';
    }

    /**
     * The abstract operation throws an error if its argument is a value that
     * cannot be converted to an Object, otherwise returns the argument.
     *
     * @private
     * @function
     * @param {*} inputArg The object to be tested.
     * @throws {TypeError} If inputArg is null or undefined.
     * @returns {*} The inputArg if coercible.
     * @see https://goo.gl/5GcmVq
     */
    function $requireObjectCoercible(inputArg) {
        var errStr;

        if (inputArg === null || $isUndefined(inputArg)) {
            errStr = 'Cannot convert argument to object: ' + inputArg;
            throw new TypeError(errStr);
        }

        return inputArg;
    }

    /**
     * The abstract operation converts its argument to a value of type string
     *
     * @private
     * @function
     * @param {*} inputArg
     * @returns {string}
     * @see https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tostring
     */
    function $toString(inputArg) {
        var type,
            val;

        if (inputArg === null) {
            val = 'null';
        } else {
            type = typeof inputArg;
            if (type === 'string') {
                val = inputArg;
            } else if (type === 'undefined') {
                val = type;
            } else {
                if (type === 'symbol') {
                    throw new TypeError('Cannot convert symbol to string');
                }

                val = String(inputArg);
            }
        }

        return val;
    }

    /**
     * Returns a string only if the arguments is coercible otherwise throws an
     * error.
     *
     * @private
     * @function
     * @param {*} inputArg
     * @throws {TypeError} If inputArg is null or undefined.
     * @returns {string}
     */
    function $onlyCoercibleToString(inputArg) {
        return $toString($requireObjectCoercible(inputArg));
    }

    /**
     * The function evaluates the passed value and converts it to an integer.
     *
     * @private
     * @function
     * @param {*} inputArg The object to be converted to an integer.
     * @returns {number} If the target value is NaN, null or undefined, 0 is
     *                   returned. If the target value is false, 0 is returned
     *                   and if true, 1 is returned.
     * @see http://www.ecma-international.org/ecma-262/5.1/#sec-9.4
     */
    function $toInteger(inputArg) {
        var number = +inputArg,
            val = 0;

        if ($strictEqual(number, number)) {
            if (!number || number === Infinity || number === -Infinity) {
                val = number;
            } else {
                val = (number > 0 || -1) * Math.floor(Math.abs(number));
            }
        }

        return val;
    }

    /**
     * Copies a regex object. Allows adding and removing native flags while
     * copying the regex.
     *
     * @private
     * @function
     * @param {RegExp} regex Regex to copy.
     * @param {Object} [options] Allows specifying native flags to add or
     *                           remove while copying the regex.
     * @returns {RegExp} Copy of the provided regex, possibly with modified
     *                   flags.
     */
    function $copyRegExp(regex, options) {
        var flags,
            opts,
            rx;

        if (options !== null && typeof options === 'object') {
            opts = options;
        } else {
            opts = {};
        }

        // Get native flags in use
        flags = getNativeFlags.exec($toString(regex))[1];
        flags = $onlyCoercibleToString(flags);
        if (opts.add) {
            flags += opts.add;
            flags = flags.replace(clipDups, '');
        }

        if (opts.remove) {
            // Would need to escape `options.remove` if this was public
            rx = new RegExp('[' + opts.remove + ']+', 'g');
            flags = flags.replace(rx, '');
        }

        return new RegExp(regex.source, flags);
    }

    /**
     * The abstract operation ToLength converts its argument to an integer
     * suitable for use as the length of an array-like object.
     *
     * @private
     * @function
     * @param {*} inputArg The object to be converted to a length.
     * @returns {number} If len <= +0 then +0 else if len is +INFINITY then
     *                   2^53-1 else min(len, 2^53-1).
     * @see https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
     */
    function $toLength(inputArg) {
        return Math.min(Math.max($toInteger(inputArg), 0), MAX_SAFE_INTEGER);
    }

    /**
     * Copies a regex object so that it is suitable for use with searchOf and
     * searchLastOf methods.
     *
     * @private
     * @function
     * @param {RegExp} regex Regex to copy.
     * @returns {RegExp}
     */
    function $toSearchRegExp(regex) {
        return $copyRegExp(regex, {
            add: 'g',
            remove: 'y'
        });
    }

    /**
     * Returns true if the operand inputArg is a member of one of the types
     * Undefined, Null, Boolean, Number, Symbol, or String.
     *
     * @private
     * @function
     * @param {*} inputArg
     * @returns {boolean}
     * @see https://goo.gl/W68ywJ
     * @see https://goo.gl/ev7881
     */
    function $isPrimitive(inputArg) {
        var type = typeof inputArg;

        return type === 'undefined' ||
                inputArg === null ||
                type === 'boolean' ||
                type === 'string' ||
                type === 'number' ||
                type === 'symbol';
    }

    /**
     * The abstract operation converts its argument to a value of type Object
     * but fixes some environment bugs.
     *
     * @private
     * @function
     * @param {*} inputArg The argument to be converted to an object.
     * @throws {TypeError} If inputArg is not coercible to an object.
     * @returns {Object} Value of inputArg as type Object.
     * @see http://www.ecma-international.org/ecma-262/5.1/#sec-9.9
     */
    function $toObject(inputArg) {
        var object;

        if ($isPrimitive($requireObjectCoercible(inputArg))) {
            object = Object(inputArg);
        } else {
            object = inputArg;
        }

        return object;
    }

    /**
     * Converts a single argument that is an array-like object or list (eg.
     * arguments, NodeList, DOMTokenList (used by classList), NamedNodeMap
     * (used by attributes property)) into a new Array() and returns it.
     * This is a partial implementation of the ES6 Array.from
     *
     * @private
     * @function
     * @param {Object} arrayLike
     * @returns {Array}
     */
    function $toArray(arrayLike) {
        var object = $toObject(arrayLike),
            length = $toLength(object.length),
            array = [],
            index = 0;

        array.length = length;
        while (index < length) {
            array[index] = object[index];
            index += 1;
        }

        return array;
    }

    if (!String.prototype.searchOf) {
        /**
         * This method returns the index within the calling String object of
         * the first occurrence of the specified value, starting the search at
         * fromIndex. Returns -1 if the value is not found.
         *
         * @function
         * @this {string}
         * @param {RegExp|string} regex A regular expression object or a String.
         *                              Anything else is implicitly converted to
         *                              a String.
         * @param {Number} [fromIndex] The location within the calling string
         *                             to start the search from. It can be any
         *                             integer. The default value is 0. If
         *                             fromIndex < 0 the entire string is
         *                             searched (same as passing 0). If
         *                             fromIndex >= str.length, the method will
         *                             return -1 unless searchValue is an empty
         *                             string in which case str.length is
         *                             returned.
         * @returns {Number} If successful, returns the index of the first
         *                   match of the regular expression inside the
         *                   string. Otherwise, it returns -1.
         */
        $defineProperty(String.prototype, 'searchOf', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function (regex) {
                var str = $onlyCoercibleToString(this),
                    args = $toArray(arguments),
                    result = -1,
                    fromIndex,
                    match,
                    rx;

                if (!$isRegExp(regex)) {
                    return String.prototype.indexOf.apply(str, args);
                }

                if ($toLength(args.length) > 1) {
                    fromIndex = +args[1];
                    if (fromIndex < 0) {
                        fromIndex = 0;
                    }
                } else {
                    fromIndex = 0;
                }

                if (fromIndex >= $toLength(str.length)) {
                    return result;
                }

                rx = $toSearchRegExp(regex);
                rx.lastIndex = fromIndex;
                match = rx.exec(str);
                if (match) {
                    result = +match.index;
                }

                return result;
            }
        });
    }

    if (!String.prototype.searchLastOf) {
        /**
         * This method returns the index within the calling String object of
         * the last occurrence of the specified value, or -1 if not found.
         * The calling string is searched backward, starting at fromIndex.
         *
         * @function
         * @this {string}
         * @param {RegExp|string} regex A regular expression object or a String.
         *                              Anything else is implicitly converted to
         *                              a String.
         * @param {Number} [fromIndex] Optional. The location within the
         *                             calling string to start the search at,
         *                             indexed from left to right. It can be
         *                             any integer. The default value is
         *                             str.length. If it is negative, it is
         *                             treated as 0. If fromIndex > str.length,
         *                             fromIndex is treated as str.length.
         * @returns {Number} If successful, returns the index of the first
         *                   match of the regular expression inside the
         *                   string. Otherwise, it returns -1.
         */
        $defineProperty(String.prototype, 'searchLastOf', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function (regex) {
                var str = $onlyCoercibleToString(this),
                    args = $toArray(arguments),
                    result = -1,
                    fromIndex,
                    length,
                    match,
                    pos,
                    rx;

                if (!$isRegExp(regex)) {
                    return String.prototype.lastIndexOf.apply(str, args);
                }

                length = $toLength(str.length);
                if (!$strictEqual(args[1], args[1])) {
                    fromIndex = length;
                } else {
                    if ($toLength(args.length) > 1) {
                        fromIndex = $toInteger(args[1]);
                    } else {
                        fromIndex = length - 1;
                    }
                }

                if (fromIndex >= 0) {
                    fromIndex = Math.min(fromIndex, length - 1);
                } else {
                    fromIndex = length - Math.abs(fromIndex);
                }

                pos = 0;
                rx = $toSearchRegExp(regex);
                while (pos <= fromIndex) {
                    rx.lastIndex = pos;
                    match = rx.exec(str);
                    if (!match) {
                        break;
                    }

                    pos = +match.index;
                    if (pos <= fromIndex) {
                        result = pos;
                    }

                    pos += 1;
                }

                return result;
            }
        });
    }
}());

(function () {
    'use strict';

    /*
     * testing as follow to make sure that at least for one character regexp,
     * the result is the same as if we used indexOf
     */

    var pre = document.getElementById('out');

    function log(result) {
        pre.appendChild(document.createTextNode(result + '\n'));
    }

    function test(str) {
        var i = str.length + 2,
            r,
            a,
            b;

        while (i) {
            a = str.indexOf('a', i);
            b = str.searchOf(/a/, i);
            r = ['Failed', 'searchOf', str, i, a, b];
            if (a === b) {
                r[0] = 'Passed';
            }

            log(r);
            a = str.lastIndexOf('a', i);
            b = str.searchLastOf(/a/, i);
            r = ['Failed', 'searchLastOf', str, i, a, b];
            if (a === b) {
                r[0] = 'Passed';
            }

            log(r);
            i -= 1;
        }
    }

    /*
     * Look for the a among the xes
     */

    test('xxx');
    test('axx');
    test('xax');
    test('xxa');
    test('axa');
    test('xaa');
    test('aax');
    test('aaa');
}());
<pre id="out"></pre>


0

यदि आप RegExp के साथ एक बहुत ही सरल lastIndex लुकअप की तलाश कर रहे हैं और परवाह नहीं है कि यह अंतिम विवरण के लिए lastIndexOf की नकल करता है, तो यह आपका ध्यान आकर्षित कर सकता है।

मैं केवल स्ट्रिंग को उल्टा करता हूं, और पहली घटना सूचकांक को लंबाई से घटाता हूं - 1. यह मेरी परीक्षा उत्तीर्ण करने के लिए होता है, लेकिन मुझे लगता है कि लंबे तारों के साथ एक प्रदर्शन मुद्दा उत्पन्न हो सकता है।

interface String {
  reverse(): string;
  lastIndex(regex: RegExp): number;
}

String.prototype.reverse = function(this: string) {
  return this.split("")
    .reverse()
    .join("");
};

String.prototype.lastIndex = function(this: string, regex: RegExp) {
  const exec = regex.exec(this.reverse());
  return exec === null ? -1 : this.length - 1 - exec.index;
};

0

मैंने String.prototype.match(regex)स्ट्रिंग में दिए गए सभी पाए गए मिलानों के एक स्ट्रिंग सरणी का उपयोग किया है regex(अधिक जानकारी यहां देखें ):

function getLastIndex(text, regex, limit = text.length) {
  const matches = text.match(regex);

  // no matches found
  if (!matches) {
    return -1;
  }

  // matches found but first index greater than limit
  if (text.indexOf(matches[0] + matches[0].length) > limit) {
    return -1;
  }

  // reduce index until smaller than limit
  let i = matches.length - 1;
  let index = text.lastIndexOf(matches[i]);
  while (index > limit && i >= 0) {
    i--;
    index = text.lastIndexOf(matches[i]);
  }
  return index > limit ? -1 : index;
}

// expect -1 as first index === 14
console.log(getLastIndex('First Sentence. Last Sentence. Unfinished', /\. /g, 10));

// expect 29
console.log(getLastIndex('First Sentence. Last Sentence. Unfinished', /\. /g));


0
var mystring = "abc ab a";
var re  = new RegExp("ab"); // any regex here

if ( re.exec(mystring) != null ){ 
   alert("matches"); // true in this case
}

मानक नियमित अभिव्यक्ति का उपयोग करें:

var re  = new RegExp("^ab");  // At front
var re  = new RegExp("ab$");  // At end
var re  = new RegExp("ab(c|d)");  // abc or abd

-2

खैर, जैसा कि आप सिर्फ एक चरित्र की स्थिति से मेल खाते हैं , रेगेक्स संभवतः ओवरकिल है।

मुझे लगता है कि आप सभी चाहते हैं, "इन वर्णों में से पहला ढूंढें" के बजाय, बस इन वर्णों में से पहला ढूंढें।

यह निश्चित रूप से सरल उत्तर है, लेकिन करता है कि आपका प्रश्न क्या करने के लिए सेट करता है, यद्यपि रेगेक्स भाग के बिना (क्योंकि आपने स्पष्ट नहीं किया था कि विशेष रूप से इसे रेग्क्स क्यों होना था)

function mIndexOf( str , chars, offset )
{
   var first  = -1; 
   for( var i = 0; i < chars.length;  i++ )
   {
      var p = str.indexOf( chars[i] , offset ); 
      if( p < first || first === -1 )
      {
           first = p;
      }
   }
   return first; 
}
String.prototype.mIndexOf = function( chars, offset )
{
   return mIndexOf( this, chars, offset ); # I'm really averse to monkey patching.  
};
mIndexOf( "hello world", ['a','o','w'], 0 );
>> 4 
mIndexOf( "hello world", ['a'], 0 );
>> -1 
mIndexOf( "hello world", ['a','o','w'], 4 );
>> 4
mIndexOf( "hello world", ['a','o','w'], 5 );
>> 6
mIndexOf( "hello world", ['a','o','w'], 7 );
>> -1 
mIndexOf( "hello world", ['a','o','w','d'], 7 );
>> 10
mIndexOf( "hello world", ['a','o','w','d'], 10 );
>> 10
mIndexOf( "hello world", ['a','o','w','d'], 11 );
>> -1

बंदर की पैचिंग के बारे में बस एक टिप्पणी - जब मैं इसकी समस्याओं से अवगत हूं - आपको लगता है कि वैश्विक नाम स्थान को प्रदूषित करना बेहतर है? यह ऐसा नहीं है जैसा कि BOTH मामलों में प्रतीक संघर्ष नहीं हो सकता है, और मूल रूप से एक ही समस्या का समाधान होना चाहिए उसी तरह से refactored / मरम्मत की जाती है।
पीटर बैली

वैसे मुझे कुछ मामलों में \ _ की खोज करने की आवश्यकता है और मैं उम्मीद कर रहा था कि मुझे सभी संभावनाओं की गणना करने की आवश्यकता नहीं है।
पैट

BaileyP: आप वैश्विक नाम स्थान प्रदूषण के बिना इस समस्या को हल कर सकते हैं, अर्थात: उदाहरण के लिए jQuery देखें। उस मॉडल का उपयोग करें। परियोजना के लिए एक वस्तु, आपका सामान इसके अंदर चला जाता है। मूतूलों ने मेरे मुँह में एक बुरा स्वाद छोड़ दिया।
केंट फ्रेड्रिक

यह भी ध्यान दिया जाना चाहिए कि जैसा मैंने वहां लिखा था वैसा कभी नहीं। उदाहरण का उपयोग मामले के कारणों के लिए सरलीकृत किया गया था।
केंट फ्रेड्रिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.