RegExp এর এক্সিকিউট () ফাংশন এবং স্ট্রিংয়ের ম্যাচ () ফাংশনের মধ্যে পার্থক্য কী?


122

যদি আমি এটি চালাই:

/([^\/]+)+/g.exec('/a/b/c/d');

বুঝতে পেরেছি:

["a", "a"]

তবে আমি যদি এটি চালাই:

'/a/b/c/d'.match(/([^\/]+)+/g);

তারপরে আমি এর প্রত্যাশিত ফলাফলটি পেয়েছি:

["a", "b", "c", "d"]

পার্থক্য কি?


4
execসমস্ত উপ-নির্বাচন পেতে আপনি লুপ করেছেন ।
zzzzBov

2
মনে রাখবেন যে দ্বিতীয়টি ইতিমধ্যে সমস্ত উপ-এক্সপ্রেশন ফিরে আসার +পরে প্রয়োজন নেই match.execপ্রতিবার কেবল একটি করে ফেরত দেয়, সুতরাং এটিরও দরকার নেই +
pimvdb

3
তার উপরে, দুটি প্লাসের মতো নেস্টেড কোয়ান্টিফায়ারগুলি অত্যন্ত সাবধানতার সাথে ব্যবহার করা উচিত কারণ এগুলি সহজেই বিপর্যয়কর ব্যাকট্র্যাকিংয়ের দিকে পরিচালিত করে
মারিয়াস শুলজ

1
@ মারিয়াসস্কুলজ লিঙ্কটির জন্য ধন্যবাদ। এটি আমাকে অধিকারী কোয়ান্টিফায়ার এবং পারমাণবিক গোষ্ঠীকরণ সম্পর্কে শিখতে পরিচালিত করে। বুঝতে খুব সুন্দর জিনিস।
জাস্টিন ওয়ার্কেন্টিন

উত্তর:


117

execএকটি বিশ্বব্যাপী নিয়মিত প্রকাশের সাথে একটি লুপ ব্যবহার করা বোঝানো হয়, কারণ এটি এখনও সমস্ত মিলিত subexpressions পুনরুদ্ধার করবে। তাই:

var re = /[^\/]+/g;
var match;

while (match = re.exec('/a/b/c/d')) {
    // match is now the next match, in array form.
}

// No more matches.

String.match এটি আপনার জন্য করে এবং বন্দী গোষ্ঠীগুলি ত্যাগ করে।


39
এই উত্তরে আমার যোগ করার মতো কিছু আছে, নিয়মিত প্রকাশকে আক্ষরিক অর্থে শর্তের মধ্যে রাখা উচিত নয়, while(match = /[^\/]+/g.exec('/a/b/c/d')এটির মতো বা এটি অসীম লুপ তৈরি করবে! এটি এমডিএন বিকাশকারী
মোজিলা.আর.ইন.ইউএস

7
@ আইয়ো: আরও সুনির্দিষ্টভাবে বলতে গেলে এটি একই নিয়মিত অভিব্যক্তি বস্তু হতে হবে। আক্ষরিক তা সম্পাদন করে না।
রাই-

@ রাই- আমি মনে করি যে এই আচরণটি ES5 তে প্রবর্তিত হয়েছিল তা নোট করা উচিত। ইএস 5 এর আগে new RegExp("pattern")এবং /pattern/বিভিন্ন জিনিস বোঝানো।
রবার্ট

75

একটি ছবি আরও ভাল, আপনি জানেন ...

re_once = /([a-z])([A-Z])/
re_glob = /([a-z])([A-Z])/g

st = "aAbBcC"

console.log("match once="+ st.match(re_once)+ "  match glob="+ st.match(re_glob))
console.log("exec once="+ re_once.exec(st) + "   exec glob="+ re_glob.exec(st))
console.log("exec once="+ re_once.exec(st) + "   exec glob="+ re_glob.exec(st))
console.log("exec once="+ re_once.exec(st) + "   exec glob="+ re_glob.exec(st))

পার্থক্যটা দেখ?

দ্রষ্টব্য: হাইলাইট করার জন্য, লক্ষ্য করুন যে ক্যাপচার করা গোষ্ঠীগুলি (যেমন: ক, এ) ম্যাচিং প্যাটার্ন (যেমন: এএ) এর পরে ফিরে আসে, এটি কেবল মেলে নিদর্শন নয় not


28

/regex/.exec()কেবলমাত্র পাওয়া প্রথম ম্যাচটি "string".match()প্রত্যাবর্তন করে , যখন আপনি gরেজেজেটে পতাকা ব্যবহার করেন তবে তাদের সমস্তকেই ফেরত দেয় ।

এখানে দেখুন: নির্বাহ , মিল


23

যদি আপনার রেজেক্স বিশ্বব্যাপী হয় এবং আপনি ক্যাপচার করছেন তবে আপনাকে অবশ্যই এক্সিকিউট ব্যবহার করতে হবে। মিল আপনার সমস্ত ক্যাপচার ফেরত দেবে না।

ম্যাচটি যখন মিলবে তখন কেবল দুর্দান্ত (ক্যাপচারিং নয়) দুর্দান্ত কাজ করে। আপনি এটি একবার চালান এবং এটি সমস্ত ম্যাচের একটি অ্যারে দেয়। (যদিও রেজেক্সটি বিশ্বব্যাপী না হলে ম্যাচটি ক্যাপচারগুলি অনুসরণ করে ম্যাচটি দেখায়)

ক্যাপচার করার সময় এক্সিকিউট হ'ল আপনি যা ব্যবহার করেন এবং প্রতিবার এটি কার্যকর করা হলে এটি ম্যাচটি দেয় এবং তারপরে ক্যাপচারগুলি অনুসরণ করে। (ম্যাচ পুরো ম্যাচটি ক্যাপচারের পরে দেওয়ার পদ্ধতিতে আচরণ করবে, কেবলমাত্র যখন রেজেক্স বিশ্বব্যাপী নয়)।

এক্সেকের সাথে আর একটি ব্যবহার ম্যাচের সূচক বা অবস্থান পাচ্ছে। আপনার রেজেেক্সের জন্য যখন কোনও পরিবর্তনশীল থাকে, আপনি .lastIndex ব্যবহার করতে পারেন এবং মিলের অবস্থানটি পেতে পারেন। একটি রেজেক্স অবজেক্টে .lastIndex থাকে এবং রেজেক্স অবজেক্টটি হ'ল আপনি কী। এক্সেক করেন on ডট ম্যাচটি স্ট্রিংয়ে সম্পন্ন হয় এবং আপনি তখন রেজেক্স অবজেক্ট ডট লাস্ট ইন্ডেক্স করতে সক্ষম হবেন না

একটি স্ট্রিংয়ের সাথে ম্যাচ ফাংশন থাকে, যা একটি রেজেক্স পাস হয়। এবং একটি রেজেক্সে এক্সিকিউটিভ ফাংশন রয়েছে এবং একটি স্ট্রিং উত্তীর্ণ হয়

এক্সিকিউট আপনি একাধিক বার চালানো। ম্যাচ আপনি একবার চালানো

ক্যাপচার না করার সময় ম্যাচটি ব্যবহার করা ভাল এবং ক্যাপচার করার সময় আপনি এক্সিকিউটি ব্যবহার করতে পারেন যা ক্যাপচার পাওয়ার জন্য ভাল কারণ এটি ক্যাপচার করার সময় আপনি যদি ম্যাচ ব্যবহার করেন তবে দেখুন যখন রেজেক্স গ্লোবাল নয় তখন ক্যাপচারগুলি দেখায় তবে তা না রেজেক্স বিশ্বব্যাপী হলে ক্যাপচারগুলি দেখায় না।

> "azb".match(/a(z)b/);
[ "azb", "z" ]

> "azb".match(/a(z)b/g);
[ "azb" ]
>

আরেকটি বিষয় হ'ল আপনি যদি এক্সিকিউটি ব্যবহার করেন তবে নোটটি যা রেজেক্সকে ডেকে আনা হয়েছে, তারপরে আপনি যদি রেজেক্সের জন্য একটি ভেরিয়েবল ব্যবহার করেন তবে আপনার আরও ক্ষমতা থাকবে

আপনি যখন রেজেক্সের জন্য ভেরিয়েবলটি ব্যবহার করবেন না তখন আপনি ম্যাচগুলি পাবেন না, তাই এক্সিকিউটিভ ব্যবহার করার সময়, রেইগেক্সের জন্য ভেরিয়েবলটি ব্যবহার করুন

> /./g.exec("abc")
[ "a" ]
> /./g.exec("abc")
[ "a" ]
> /./g.exec("abc")
[ "a" ]
>
> /[a-c]/g.exec("abc")
[ "a" ]
> /[a-c]/g.exec("abc")
[ "a" ]
>

> var r=/[a-c]/g
> r.exec("abc")
[ "a" ]
> r.exec("abc")
[ "b" ]
> r.exec("abc")
[ "c" ]
> r.exec("abc")
null
>

এবং এক্সিকিউট দিয়ে, আপনি ম্যাচের "সূচক" পেতে পারেন get

> var r=/T/g
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
2
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
6
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
9
> r.exec("qTqqqTqqTq");
null
> r.lastIndex
0
>

সুতরাং যদি আপনি সূচকগুলি বা ক্যাপচারিং চান, তবে এক্সিকিউটিভ ব্যবহার করুন (মনে রাখবেন যে আপনি দেখতে পাচ্ছেন যে "সূচক" এর সাথে এটি "সূচক" দেয় এটি সত্যই একটি নবম ঘটনা, এটি 1 থেকে গণনা করা হয়) সুতরাং আপনি যথাযথ আবিষ্কার করতে পারেন ১. বিয়োগ করে সূচক 1 এবং আপনি দেখতে পাচ্ছেন যে এটি 0 - সর্বশেষতম 0 দেয় - খুঁজে পাওয়া যায় নি।

এবং আপনি যদি ম্যাচটি প্রসারিত করতে চান, আপনি ক্যাপচার করার সময় আপনি এটি ব্যবহার করতে পারেন, কিন্তু যখন রেজেক্স বিশ্বব্যাপী নয়, এবং যখন আপনি এটির জন্য করেন, তখন অ্যারের সামগ্রীগুলি সমস্ত ম্যাচ নয়, তবে পূর্ণ ম্যাচ পরে ক্যাপচার।


হ্যাঁ, কাজ বুঝতে r.lastIndexমধ্যে পার্থক্য বুঝতে চাবিকাঠি ফ্যাক্টর execএবং match
রান করুন

@ বারলপ "ম্যাচটি সমস্ত ক্যাপচারের সাথে মিলবে না", গুরুত্ব সহকারে? "a, b, c, aa, bb, cc"। ম্যাচ (/ (\ w +) / g) => ["ক", "বি", "সি", "আ", "বিবি", "সিসি" ]। এটি কীভাবে ব্যাখ্যা করবেন যে এটি সমস্তকেই ক্যাশে করেছে?
মিঃ হিডেন

@ বারলপ If your regex is global, and you are capturing, then you must use exec. Match won't return all your captures.আমি এটি কনসোলে পেয়েছি। কেবল "a,b,c,aa,bb,cc".match(/(\w+)/g);অপেরা, ফায়ারফক্সের অনুলিপি / পেস্ট করুন ।
মিঃ হিডেন

@ শ্রীহাইডে আমি আপনার ভাষাটি আপনার ভুল উক্তিটিতে ব্যবহার করব না। এবং কী বিষয়গুলি কী দেখানো হয় এবং আমরা কী দেখতে সক্ষম তা হ'ল .. পর্দার আড়ালে কোনও ক্যাশে রয়েছে কিনা তাও প্রাসঙ্গিক নয়। এবং আমি এটি দেখার পরে অনেকক্ষণ হয়ে গেছে, তবে এটি সমস্ত ক্যাপচার দেখায় না ... আপনি যদি নিজের উদাহরণটি করেন "a,b,c,aa,bb,cc".match(/(\w+)/g) তবে সেখানে যা ঘটছে তা এটি সমস্ত ম্যাচ দেখায়, এবং ঠিক তাই ঘটে যে আপনি প্রতিটি ম্যাচ ক্যাপচার করেছেন, তাই যদি এটি সমস্ত ক্যাপচার দেখানো হয় তবে এটি দেখতে ঠিক একই রকম হবে (সিএনডি)
বার্লপ

(সিএনডিডি) সুতরাং আপনি ভাবছেন যে এটি ক্যাপচারগুলি দেখায়, কিন্তু এটি নয়, এটি ম্যাচগুলি
দেখায়

6

ম্যাচ () ফাংশনটি str.match(regexp)নিম্নলিখিতটি করবে:

  • যদি হয় একটি ম্যাচ তা ফেরত হবে:
    • যদি gপতাকা হয় regexp ব্যবহৃত: এটা সব সাবস্ট্রিং ফিরে আসবে (ক্যাপচার গ্রুপ উপেক্ষা)
    • যদি gপতাকা না regexp ব্যবহৃত: এটা হিসাবে একই ফিরে আসবেregexp.exec(str)
  • আছে যদি কোন ম্যাচ তা ফেরত হবে:
    • null

পতাকা ব্যবহার করে । ম্যাচ () এর উদাহরণ g:

var str = "qqqABApppabacccaba";
var e1, e2, e3, e4, e5;
e1 = str.match(/nop/g); //null
e2 = str.match(/no(p)/g); //null
e3 = str.match(/aba/g); //["aba", "aba"]
e4 = str.match(/aba/gi); //["ABA", "aba", "aba"]
e5 = str.match(/(ab)a/g); //["aba", "aba"] ignoring capture groups as it is using the g flag

আর .match () ছাড়া gপতাকা সমতূল্য .exec () :

e1=JSON.stringify(str.match(/nop/))===JSON.stringify(/nop/.exec(str)); //true
//e2 ... e4 //true
e5=JSON.stringify(str.match(/(ab)a/))===JSON.stringify(/(ab)a/.exec(str)); //true

.Exec () ফাংশন regexp.exec(str)নিম্নলিখিত কাজগুলো করবে:

  • যদি হয় একটি ম্যাচ তা ফেরত হবে:
    • যদি gপতাকা হয় regexp ব্যবহৃত: এটা ফিরে আসবে (প্রতিটি সময় এটা বলা হয় এর জন্য) : [N_MatchedStr, N_Captured1, N_Captured2, ...]পরের Nম্যাচ। গুরুত্বপূর্ণ: regexp অবজেক্টটি যদি কোনও ভেরিয়েবলে সংরক্ষণ না করা হয় তবে এটি পরবর্তী ম্যাচে অগ্রসর হবে না (এটি একই বস্তু হওয়া দরকার)
    • যদি gপতাকা না regexp ব্যবহৃত: এটা যেমন যদি এটি একটি ছিল একই ফিরে আসবে gপতাকা এবং প্রথম সময় এবং শুধুমাত্র একবার ডাক দিলেন ড।
  • আছে যদি কোন ম্যাচ তা ফেরত হবে:
    • null

.Exec () এর উদাহরণ ( gফ্ল্যাগ ব্যবহার করে সঞ্চিত regexp + = এটি প্রতিটি কলের সাথে পরিবর্তিত হয়):

var str = "qqqABApppabacccaba";
var myexec, rgxp = /(ab)a/gi;

myexec = rgxp.exec(str);
console.log(myexec); //["ABA", "AB"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "ab"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "ab"]
myexec = rgxp.exec(str);
console.log(myexec); //null

//But in this case you should use a loop:
var mtch, myRe = /(ab)a/gi;
while(mtch = myRe.exec(str)){ //infinite looping with direct regexps: /(ab)a/gi.exec()
    console.log("elm: "+mtch[0]+" all: "+mtch+" indx: "+myRe.lastIndex);
    //1st iteration = elm: "ABA" all: ["ABA", "AB"] indx: 6
    //2nd iteration = elm: "aba" all: ["aba", "ab"] indx: 12
    //3rd iteration = elm: "aba" all: ["aba", "ab"] indx: 18
}

.Exec () এর উদাহরণগুলি যখন প্রতিটি কলের সাথে এটি পরিবর্তন হয় না :

var str = "qqqABApppabacccaba", myexec, myexec2;

//doesn't go into the next one because no g flag
var rgxp = /(a)(ba)/;
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "a", "ba"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "a", "ba"]
//... ["aba", "a", "ba"]

//doesn't go into the next one because direct regexp
myexec2 = /(ab)a/gi.exec(str);
console.log(myexec2); //["ABA", "AB"]
myexec2 = /(ab)a/gi.exec(str);
console.log(myexec2); //["ABA", "AB"]
//... ["ABA", "AB"]

1

কখনও কখনও regex.exec () এর পরে স্ট্রিং.ম্যাচ () অনেক বেশি সময় নেয়।

এটি উল্লেখ করার মতো বিষয় যে স্ট্রিং.ম্যাচ () এবং রিজেক্স.এক্সেক () এর ফলাফল যদি একই হয় (উদা: যখন flag জি পতাকা ব্যবহার না করা হয়), তবে রিজেক্স.এক্সেক () x2 থেকে x30 এর মধ্যে স্ট্রিংটি কোথাও নিয়ে যাবে। ম্যাচ():

সুতরাং এই জাতীয় ক্ষেত্রে, "নতুন রেজিএক্সপ্যাক্স ()। এক্সিকিউটি ()" ব্যবহার করার পদ্ধতিটি কেবল তখনই ব্যবহার করা উচিত যখন আপনার একটি গ্লোবাল রেজেক্স প্রয়োজন (অর্থাত্ একাধিকবার কার্যকর করতে)।


1
আপনার কি একটি মানদণ্ড আছে?
সান ট্রেন-এনগুইন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.