javascript - समझ - प्रपत्र एचटीएमएल




आप जावास्क्रिप्ट नियमित अभिव्यक्ति में मिलान किए गए समूहों तक कैसे पहुंचते हैं? (10)

इस उत्तर में उपयोग की जाने वाली शब्दावली:

  • मिलान आपकी स्ट्रिंग के खिलाफ अपने RegEx पैटर्न को चलाने के परिणाम को इंगित करता है: someString.match(regexPattern)
  • मिलान पैटर्न इनपुट स्ट्रिंग के सभी मिलान वाले हिस्सों को इंगित करते हैं, जो सभी मैच सरणी के अंदर रहते हैं। इनपुट स्ट्रिंग के अंदर ये आपके पैटर्न के सभी उदाहरण हैं।
  • मिलान किए गए समूह रेगेक्स पैटर्न में परिभाषित सभी समूहों को पकड़ने के लिए इंगित करते हैं। (कोष्ठक के अंदर पैटर्न, जैसे: /format_(.*?)/g , जहां (.*?) एक मिलान समूह होगा।) ये मिलान पैटर्न के भीतर रहते हैं।

विवरण

मिलान किए गए समूहों तक पहुंच प्राप्त करने के लिए, मिलान किए गए पैटर्न में से प्रत्येक में, आपको एक फ़ंक्शन या मैच पर पुनरावृत्ति के समान कुछ चाहिए। कई अन्य उत्तर दिखाए जाने के कई तरीके हैं, क्योंकि कई अन्य उत्तर दिखाते हैं। अधिकांश अन्य उत्तरों सभी मिलान पैटर्न पर पुनरावृत्ति करने के लिए थोड़ी देर के लूप का उपयोग करते हैं, लेकिन मुझे लगता है कि हम सभी उस दृष्टिकोण के साथ संभावित खतरों को जानते हैं। केवल पैटर्न के बजाय एक new RegExp() खिलाफ मिलान करना आवश्यक है, जिसे केवल एक टिप्पणी में उल्लिखित किया गया है। ऐसा इसलिए है क्योंकि .exec() विधि जनरेटर फ़ंक्शन के समान व्यवहार करती है - यह हर बार एक मैच होने पर .lastIndex , लेकिन इसके .lastIndex को अगले .exec() कॉल पर जारी रखने के लिए रखती है।

कोड उदाहरण

नीचे एक फ़ंक्शन searchString का एक उदाहरण है जो सभी मिलान किए गए पैटर्न का Array देता है, जहां प्रत्येक match सभी मिलान वाले समूहों के साथ एक Array होता है। थोड़ी देर के लूप का उपयोग करने के बजाय, मैंने Array.prototype.map() for सादे का उपयोग करके - Array.prototype.map() फ़ंक्शन के साथ-साथ एक और अधिक प्रदर्शन करने वाले उदाहरणों का उपयोग करके उदाहरण प्रदान किए हैं।

संक्षिप्त संस्करण (कम कोड, अधिक वाक्य रचनात्मक चीनी)

ये कम प्रदर्शन करने वाले हैं क्योंकि वे मूल रूप से तेजी से के for एक forEach लागू करने के लिए लागू करते हैं।

// Concise ES6/ES2015 syntax
const searchString = 
    (string, pattern) => 
        string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match => 
            new RegExp(pattern.source, pattern.flags)
            .exec(match));

// Or if you will, with ES5 syntax
function searchString(string, pattern) {
    return string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match =>
            new RegExp(pattern.source, pattern.flags)
            .exec(match));
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

प्रदर्शन संस्करण (अधिक कोड, कम वाक्य रचनात्मक चीनी)

// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
    let result = [];

    const matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (let i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
};

// Same thing, but with ES5 syntax
function searchString(string, pattern) {
    var result = [];

    var matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (var i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

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

मैं एक नियमित अभिव्यक्ति का उपयोग कर स्ट्रिंग के एक हिस्से से मेल खाना चाहता हूं और फिर उस कोष्ठक वाले सबस्ट्रिंग तक पहुंच सकता हूं:

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);

console.log(arr);     // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // Prints: undefined  (???)
console.log(arr[0]);  // Prints: format_undefined (!!!)

मैं क्या गलत कर रहा हूं?

मैंने पाया है कि उपरोक्त नियमित अभिव्यक्ति कोड में कुछ भी गलत नहीं था: वास्तविक स्ट्रिंग जिसका मैं परीक्षण कर रहा था यह था:

"date format_%A"

रिपोर्ट करना कि "% ए" अनिर्धारित है, वह बहुत अजीब व्यवहार प्रतीत होता है, लेकिन यह सीधे इस प्रश्न से संबंधित नहीं है, इसलिए मैंने एक नया खोला है, जावास्क्रिप्ट में एक मिलान किए गए सबस्ट्रिंग को "अपरिभाषित" क्यों लौटा रहा है?

मुद्दा यह था कि console.log अपने पैरामीटर को printf कथन की तरह लेता है, और चूंकि मैं जिस स्ट्रिंग को लॉगिंग कर रहा था ( "%A" ) का एक विशेष मान था, तो वह अगले पैरामीटर के मान को खोजने का प्रयास कर रहा था।


अंतिम लेकिन कम से कम नहीं, मैंने पाया कि एक लाइन कोड जो मेरे लिए ठीक काम करता है (जेएस ईएस 6):

var reg = /#([\S]+)/igm; //get hashtags
var string = 'mi alegría es total! ✌🙌\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';

var matches = string.match(reg).map(e => e.replace(reg, '$1'));
console.log(matches);

यह वापस आ जाएगा: [fiestasdefindeaño, PadreHijo, buenosmomentos, france, paris]


आप इस तरह के कैप्चरिंग समूहों तक पहुंच सकते हैं:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc

और यदि कई मैचों हैं तो आप उन पर पुन: प्रयास कर सकते हैं:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
  // matched text: match[0]
  // match start: match.index
  // capturing group n: match[n]
  console.log(match[0])
  match = myRegexp.exec(myString);
}


आपका कोड मेरे लिए काम करता है (मैक पर एफएफ 3) भले ही मैं सहमत कि रेगेक्स शायद होना चाहिए:

/\bformat_(.*?)\b/

(लेकिन, ज़ाहिर है, मुझे यकीन नहीं है क्योंकि मुझे रेगेक्स के संदर्भ को नहीं पता है।)


उपरोक्त मल्टी-मैच कोष्ठक उदाहरणों के संबंध में, मैं जो भी चाहता था उसे प्राप्त करने के बाद यहां एक उत्तर ढूंढ रहा था:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

ऊपर और .push () के साथ थोड़ी घुलनशील फ़ंक्शन कॉल को देखने के बाद, यह मेरे सामने आया कि समस्या को mystring.replace () के साथ बहुत सुंदर ढंग से हल किया जा सकता है (प्रतिस्थापन बिंदु नहीं है, और यह भी नहीं किया जाता है , दूसरे पैरामीटर के लिए स्वच्छ, अंतर्निहित रिकर्सिव फ़ंक्शन कॉल विकल्प है!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

इसके बाद, मुझे नहीं लगता कि मैं कभी भी कभी भी कुछ भी नहीं करने के लिए .match () का उपयोग करने जा रहा हूं।


एक लाइनर जो केवल व्यावहारिक है यदि आपके पास ब्रांड्स की एक जोड़ी है:

while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};

यहां एक विधि है जिसका उपयोग आप प्रत्येक मैच के लिए एन वें कैप्चरिंग समूह प्राप्त करने के लिए कर सकते हैं:

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);


exec विधि का आह्वान करने की कोई आवश्यकता नहीं है! आप स्ट्रिंग पर सीधे "मिलान" विधि का उपयोग कर सकते हैं। बस कोष्ठक मत भूलना।

var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...

स्थिति 0 में सभी परिणामों के साथ एक स्ट्रिंग है। स्थिति 1 में पहले मैच कोष्ठक द्वारा दर्शाया गया है, और स्थिति 2 में आपके कोष्ठक में दूसरा मिलान अलग है। नेस्टेड कोष्ठक मुश्किल हैं, इसलिए सावधान रहें!


var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);

\b बिल्कुल वही बात नहीं है। (यह format_a_b पर काम करता है, लेकिन format_a_b पर काम नहीं करता है) लेकिन मैं आपकी अभिव्यक्ति का एक विकल्प दिखाना चाहता था, जो ठीक है। बेशक, match कॉल महत्वपूर्ण बात है।


/*Regex function for extracting object from "window.location.search" string.
 */

var search = "?a=3&b=4&c=7"; // Example search string

var getSearchObj = function (searchString) {

    var match, key, value, obj = {};
    var pattern = /(\w+)=(\w+)/g;
    var search = searchString.substr(1); // Remove '?'

    while (match = pattern.exec(search)) {
        obj[match[0].split('=')[0]] = match[0].split('=')[1];
    }

    return obj;

};

console.log(getSearchObj(search));





regex