فراگیری عبارات معمول در کمتر از 20 دقیقه

ممکن است حین برنامه نویسی و کد نویسی خود با مسائلی برخورد کنید که به استفاده از عبارت معمول (Regular expressions) نیاز پیدا کنید. در اینجا دو مشکل وجود دارد. عبارات معمول ابزاری قدرتمند است که کد نویسان ماهر به عنوان آخرین راهکار از آن استفاده می کنند؛ اما وقتی از آنها استفاده می شود، بطور قاطع کاربران را مات می کند و انعطاف پذیری تا حدودی گرفته می شود

ممکن است حین برنامه نویسی و کد نویسی خود با مسائلی برخورد کنید که به استفاده از عبارت معمول (Regular expressions) نیاز پیدا کنید. در اینجا دو مشکل وجود دارد. عبارات معمول ابزاری قدرتمند است که کد نویسان ماهر به عنوان آخرین راهکار از آن استفاده می کنند؛ اما وقتی از آنها استفاده می شود، بطور قاطع کاربران را مات می کند و انعطاف پذیری تا حدودی گرفته می شود.

عبارات معمول که رجکس (regexes) نامیده می شود، زبان خاصی است که برای تعریف الگوی مورد نیاز برای همسانی با رشته های متنی استفاده می شود. عبارات معمول کدنویسی دارای گرامر و دستور زبان و قواعد مخصوص خود است و بسادگی تازه کارها را به اشتباه می اندازد. اما تمرین موجب تسلط می شود. در اینجا عبارات معمول (رجکس) بحث می شوند.

1- همسان کردن یک حرف منفرد

هر زبان برنامه نویسی راهی برای تعریف و استفاده از عبارات معمول دارد. هرچند عبارات معمول در زبان های مختلف اندکی تفاوت دارد، اما اساس استفاده از این عبارات در زبان های مختلف در اینجا بحث می شود. مثال های نوشته شده در اینجا به زبان جاوا اسکریپت می باشد، برای اینکه بتوانید با مرورگر خود آنها را اجرا کنید.

ساده ترین نوع رجکس ها آندسته است که به همسان سازی یک حرف منفرد می پردازد. قواعد آن عبارتست از:

  • نقطه (.) با هر حرفی همسان است. اگر بخواهید از نقطه به عنوان نقطه اصلی الفبا و یک حرف استفاده کنید، آن را با ممیز برعکس (\.) ارجاع دهید.
  • علامت سئوال (?) بدین معنی است که حروف بعدی اختیاری است. اگر بخواهید از علامت سئوال به عنوان حرف معمول علامت سئوال استفاده کنید و نه یک رجکس، بایستی آن را با ممیز برعکس (\?) ارجاع دهید.
var text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit lest. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu.';
// Will match both "elit" and "elat". The dot can match any character.
// Tip: try removing the "g" modifier of the regex to see what happens.
var regex = /el.t/g;
console.log( text.match(regex) );
// Will match both "est" and "lest". The question mark makes "l" optional.
var regex2 = /l?est/g;
console.log( text.match(regex2) );

خروجی اجرای این کد عبارتست از:

["elit","elat"]
["lest","est"]

2- همسان سازی با یک مجموعه حروف

با توجه به مثال فوق، می توانیم رجکس را طوری بنویسیم که با استفاده از مجموعه حروف، با حرف خاصی همسان باشد:

  • یک مجموعه از یک یا چند حرف تشکیل شده است که در داخل کروشه گذاشته شده اند مثل [abc]. رجکس تنها با یکی از این حروف بایستی مساوی باشد. در مثال فقط با حروف a، b یا c همسان خواهد بود. می توان با استفاده از حرف ^ این مجموعه را نفی کرد. [^abc] به معنی هر حرفی غیر از a، b یا c است. همچنین می توان از این طریق دامنه تعریف کرد مثل [0-9], [a-z]، که بایستی ورودی با این محدوده حروف همسان باشد.
  • مجموعه های حاضری و سرخود وجود دارد که نوشتن رجکس را راحتتر می کند (این مجموعه ها را شورت هند می نامند). مثلا بجای [0-9] می توانید \d و بجای [^0-9] می توانید \D را بنویسید. همچنین مجموعه هایی برای حروف کلمه وجود دارد (a تا z با شماره و زیرخط) مثل -\w و \W و فاصله (شامل tab و خط جدید) که -\s و \S می باشد.

مثال زیر این مسئله را روشن می کند:

// Match only "cat" and "can", but not "car".
var text = 'cat car can';
console.log( text.match(/ca[tn]/g) );
// Match everything BUT cat and can (notice the ^ symbol)
console.log( text.match(/ca[^tn]/g) );
// Here is another example, which matches only the number
text = 'I would like 8 cups of coffee, please.';
console.log('How many cups: ' + text.match( /[0-9]/g ));
// A better, shorter way to write it, using the \d character class
console.log('How many cups: ' + text.match( /\d/g ));
// Matching everything BUT the number (will return an array of chars)
console.log( text.match(/\D/g) );

خروجی اجرای این کد عبارتست از:

["cat","can"]
["car"]
How many cups: 8
How many cups: 8
["I"," ","w","o","u","l","d"," ","l","i","k","e"," "," ","c","u","p","s"," ","o","f"," ","c","o","f","f","e","e",","," ","p","l","e","a","s","e","."]

3- همسان سازی کلمات

بیشتر مواقع می خواهیم کل کلمات را همسان سازی کنیم بجای اینکه فقط یک حرف را همسان کنیم. اینکار با استفاده از مدیفایرها و تکرار حرف یا مجموعه حروف انجام می شود. این رجکس ها عبارتند از:

  • + که حرف یا مجموعه قبلی را یک یا چند بار تکرار می کند
  • * که حرف یا مجموعه قبلی را صفر بار یا بیشتر تکرار می کند
  • {x} برای تعداد دقیق تکرار ها، {x,y} برای دفعات متغیر تکرار (که در آن x و y عدد هستند)

همچنین الگوی خاص \b وجود دارد که مرزها را در پایان کلمه مشخص می کند (یک نماد واقعی نیست).

var text = 'Hello people of 1974. I come from the future. In 2014 we have laser guns, hover boards and live on the moon!';
// Find the years. \d+ will match one or more chars
var yearRegex = /\d+/g;
console.log('Years: ', text.match( yearRegex ) );
// Find all sentences. Our sentences begin with a capital letter and end in either a dot or an exclamation mark.
// The question mark makes the regex non-greedy. Try removing it.
var sentenceRegex = /[A-Z].+?(\.|!)/g;
console.log('Sentences: ', text.match(sentenceRegex) );
// Find all words that begin with h. We want to match both lower and upper case, so we include the i modifier.
// Notice the \b for word boundary. Try removing it.
var hWords = /\bh\w+/ig;
console.log('H Words: ', text.match(hWords) );
// Find all words between four and six characters
var findWords = /\b\w{4,6}\b/g;
console.log( 'Words between 4 and 6 chars: ', text.match(findWords) );
// Find words longer than 5 chars
console.log( 'Words 5 chars or longer: ', text.match(/\b\w{5,}\b/g) );
// Find words exactly 6 chars long
console.log( 'Words exactly 6 chars long: ', text.match(/\b\w{6}\b/g) );

خروجی اجرای این کد عبارتست از:

Years:["1974","2014"]
Sentences: ["Hello people of 1974.","I come from the future.","In 2014 we have laser guns, hover boards and live on the moon!"]
H Words: ["Hello","have","hover"]
Words between 4 and 6 chars: ["Hello","people","1974","come","from","future","2014","have","laser","guns","hover","boards","live","moon"]
Words 5 chars or longer: ["Hello","people","future","laser","hover","boards"]
Words exactly 6 chars long: ["people","future","boards"]

4- همسان سازی/اعتبارسنجی کامل خطوط

نمونه این الگوها استفاده از جاواسکریپت برای اعتبارسنجی ورودی کاربر در فیلدهای متنی است. اینها نیز رجکس های معمولی هستند اما در شروع و پایان متن با استفاده از ^ (اول خط) و $ (پایان خط) مشخص می شوند. این موجب می شود که الگوی نوشته شده با کل طول متن همسان سازی شود و تنها بخشی از آن همسان نشود.

همچنین می توان از متد ()test استفاده کرد که یک شی رجکس بوده و اگر رشته همسان رجکس نباشد false و در صورت همسان بودن true بر می گرداند.

// We have an array with strings. Let's extract only the URLs!
var strings = [
'https://parastar.info/posts/',
'this is not a URL',
'https://google.com/',
'123461',
'https://tutorialzine.com/?search=jquery',
'http://not a valid url',
'abc http://invalid.url/'
];
// Here is a simple regex that will do the job. Note the ^ and $ symbols for beggining and end of line.
// Try removing them and see which URLs are detected.
var regex = /^https?:\/\/[\w\/?.&-=]+$/;
var urls = [];
for( var i = 0; i < strings.length; i++ ){
if( regex.test(strings[i]) ){
// This is a valid URL
urls.push(strings[i]);
}
}
console.log('Valid URLs: ', urls);

خروجی اجرای این کد عبارتست از:

Valid URLs: ["https://parastar.info/posts/","https://google.com/","https://tutorialzine.com/?search=jquery"]

5- جستجو و جایگزین کردن

یکی از کارهایی که اغلب مستلزم استفاده از عبارات معمول یا رجکس است، جستجو جایگزینی (Search and replace) یک متن است. در اینجا دو ایده اصلی وجود دارد:

  • گروه یک مجموعه از الگوها است که در داخل پرانتز () گذاشته می شود. هر گروه متنی را تکرار می کند که با الگوی داخل آن یکسان باشد. متن همسان با هر گروه را می توان بعدا با ایندکس و پیشوند علامت دلار مشخص کرد (که با 1$ برای گروه اول شروع می شود).
  • هر گروه در الگوی خود وجود داشته که یک مرجع برگشتی است و با ممیز برعکس می شود و پس از آن ایندکس گروه می آید و با \1 شروع می شود (مثال زیر را ببینید). این خصیصه کم استفاده می شود و می توانید آن را نادیده بگیرید.
// Using backreferences
// Find the words which consist only of the same letters
var text = 'Abc ddefg, hijk lllll mnopqr ssss. Tuv wxyyy z.';
var sameLetterRegex = /\b(\w)\1*\b/g;
console.log( text.match(sameLetterRegex) );
// Let's turn "John Smith" into "Smith, John"
// Each group (\w+) matches a single word. Each group is assigned
// an index, starting from $1
var name = 'John Smith';
var nameRegex = /(\w+) (\w+)/;
console.log( name.replace(nameRegex, '$2, $1') );
// For more advanced manipulations, we need to provide a JS callback.
// For example, lets make the surname uppercase
var upcasename = name.replace(nameRegex, function(string, group1, group2){
return group2.toUpperCase() + ', ' + group1;
});
console.log(upcasename);

خروجی اجرای این کد عبارتست از:

["lllll","ssss","z"]
Smith, John
SMITH, John

اگر در اجرای این راهنما به مشکل برخورد کردید و سایر سئوالات و پیشنهادات خود را در بخش سئوالات عمومی انجمن پلکسا مطرح نمایید. گروه توسعه وب پلکسا به سئوالات شما پاسخ خواهند داد.

عضویت در خبرنامه پلکسا

در صورت تمایل ایمیل خود را وارد کنید و تازه های پلکسا را از طریق ایمیل دریافت کنید. خبرنامه الکسا هفته نامه بوده و حاوی جدیدترین مطالب و نشریات پلکسا است.

با ما شریک شوید

با ما باشید

قابل توجه وبمسترها

وبمستر گرامی

در صورتی که به دنبال جذب بازدید کننده یا ارتقای رنکینگ سایت خود هستید، پیشنهاد می کنیم پلکسا را یک پست یا مطلب مهمان کنید. همانطور که برای سایت خود مطلب می نویسید، مطلب خود را آماده و کد نویسی کرده و در پلکسا منتشر کنید. پلکسا هیچگونه دخل یا تصرفی در پست شما نخواهد داشت.