Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी रेगुलर एक्सप्रेशन्स में महारत: उन्नत पैटर्न मिलान और सत्यापन

रूबी रेगुलर एक्सप्रेशन्स (रूबी रेगेक्स संक्षेप में) आपको आगे के प्रसंस्करण के लिए डेटा निकालने के इरादे से स्ट्रिंग्स के अंदर विशिष्ट पैटर्न खोजने में मदद करते हैं।

रेगुलर एक्सप्रेशन्स के दो सामान्य उपयोग के मामलों में सत्यापन और पार्सिंग शामिल हैं।

उदाहरण के लिए:

एक ईमेल पते के बारे में सोचें, एक रूबी रेगेक्स के साथ आप परिभाषित कर सकते हैं कि एक वैध ईमेल पता कैसा दिखता है। दूसरे शब्दों में, आपका प्रोग्राम वैध और अवैध ईमेल पते के बीच अंतर बता पाएगा।

रूबी रेगुलर एक्सप्रेशन्स में महारत: उन्नत पैटर्न मिलान और सत्यापन

रूबी रेगुलर एक्सप्रेशन्स को दो फॉरवर्ड स्लैश के बीच परिभाषित किया जाता है ताकि उन्हें अन्य भाषा सिंटैक्स से अलग किया जा सके। सबसे सरल अभिव्यक्तियाँ एक शब्द या यहां तक कि एक अक्षर से मेल खाती हैं।

उदाहरण के लिए:

# 'like' शब्द खोजें
"Do you like cats?" =~ /like/ 

यदि यह मिला तो यह शब्द की पहली घटना का इंडेक्स लौटाता है (सफल मिलान) या अन्यथा nil। यदि हमें इंडेक्स की परवाह नहीं है तो हम String#include? मेथड का उपयोग कर सकते हैं।

यह जांचने का एक और तरीका है कि कोई स्ट्रिंग रेगेक्स से मेल खाती है या नहीं, match मेथड का उपयोग करना:

if "Do you like cats?".match(/like/)
  puts "Match found!"
end 

अब:

आप सीखने जा रहे हैं कि अधिक उन्नत पैटर्न कैसे बनाएं ताकि आप तारीखों, फोन नंबरों, ईमेल, URLs आदि जैसी चीजों को मिलान, कैप्चर और बदल सकें।

कैरेक्टर क्लासेस

एक कैरेक्टर क्लास आपको मिलान करने के लिए वर्णों की एक रेंज या सूची को परिभाषित करने देती है। उदाहरण के लिए, [aeiou] किसी भी स्वर से मेल खाता है।

उदाहरण: क्या स्ट्रिंग में कोई स्वर है?

def contains_vowel(str)
  str =~ /[aeiou]/
end
contains_vowel("test") # 1 लौटाता है
contains_vowel("sky") # nil लौटाता है 

यह वर्णों की मात्रा को ध्यान में नहीं रखेगा, हम जल्द ही देखेंगे कि यह कैसे करना है।

रेंजेस

हम सभी को टाइप किए बिना कई अक्षरों या संख्याओं से मिलान करने के लिए रेंजेस का उपयोग कर सकते हैं। दूसरे शब्दों में, [2-5] जैसी रेंज [2345] के समान है।

कुछ उपयोगी रेंजेस:

  • [0-9] 0 से 9 तक किसी भी संख्या से मेल खाता है
  • [a-z] a से z तक किसी भी अक्षर से मेल खाता है (कैप्स नहीं)
  • [^a-z] नकारात्मक रेंज

उदाहरण: क्या इस स्ट्रिंग में कोई संख्या है?

def contains_number(str)
  str =~ /[0-9]/
end
contains_number("The year is 2015") # 12 लौटाता है
contains_number("The cat is black") # nil लौटाता है 

याद रखें: `=~` का उपयोग करते समय रिटर्न मान या तो स्ट्रिंग इंडेक्स या `nil` होता है

कैरेक्टर रेंजेस निर्दिष्ट करने के लिए एक अच्छा संक्षिप्त सिंटैक्स है:

  • \w [0-9a-zA-Z_] के बराबर है
  • \d [0-9] के समान है
  • \s व्हाइट स्पेस से मेल खाता है (टैब्स, नियमित स्पेस, नई लाइन)

इनका नकारात्मक रूप भी है:

  • \W [0-9a-zA-Z_] में नहीं है
  • \D संख्या नहीं है
  • \S स्पेस नहीं है

डॉट कैरेक्टर . नई लाइनों को छोड़कर सब कुछ से मेल खाता है। यदि आपको शाब्दिक . का उपयोग करने की आवश्यकता है तो आपको इसे एस्केप करना होगा।

उदाहरण: विशेष वर्णों को एस्केप करना

# यदि हम एस्केप नहीं करते, तो अक्षर "5a5" से मेल खाएगा
"5a5".match(/\d.\d/)
# इस मामले में केवल शाब्दिक डॉट मेल खाता है
"5a5".match(/\d\.\d/) # nil
"5.5".match(/\d\.\d/) # मैच 

मोडिफायर्स

अब तक हम एक समय में केवल एक वर्ण से मेल खाने में सक्षम हैं। कई वर्णों से मेल खाने के लिए हम पैटर्न मोडिफायर्स का उपयोग कर सकते हैं।

मोडिफायर विवरण
+ 1 या अधिक
* 0 या अधिक
? 0 या 1
{3,5} 3 और 5 के बीच

हम अब तक जो कुछ भी सीखा है उसे मिलाकर अधिक जटिल रेगुलर एक्सप्रेशन्स बना सकते हैं।

उदाहरण: क्या यह IP पते जैसा दिखता है?

# ध्यान दें कि यह कुछ अमान्य IP पते से भी मेल खाएगा
# जैसे 999.999.999.999, लेकिन इस मामले में हमें केवल प्रारूप की परवाह है।
def ip_address?(str)
  # !! का उपयोग करके रिटर्न मान को बूलियन में बदलें
  !!(str =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)
end
ip_address?("192.168.1.1") # true लौटाता है
ip_address?("0000.0000") # false लौटाता है 

सटीक स्ट्रिंग मिलान

यदि आपको सटीक मिलान की आवश्यकता है तो आपको एक अन्य प्रकार के मोडिफायर की आवश्यकता होगी। आइए एक उदाहरण देखते हैं ताकि आप देख सकें कि मैं किस बारे में बात कर रहा हूँ:

# हम यह पता लगाना चाहते हैं कि यह स्ट्रिंग ठीक चार अक्षरों की है या नहीं, यह
# अभी भी मेल खाएगा क्योंकि इसमें चार से अधिक हैं, लेकिन यह वह नहीं है जो हम चाहते हैं।
"Regex are cool".match /\w{4}/
# इसके बजाय हम 'लाइन की शुरुआत' और 'लाइन के अंत' मोडिफायर्स का उपयोग करेंगे
"Regex are cool".match /^\w{4}$/
# इस बार यह मेल नहीं खाएगा। यह एक बल्कि बनावटी उदाहरण है, क्योंकि हम बस
# लंबाई खोजने के लिए .size का उपयोग कर सकते थे, लेकिन मुझे लगता है कि यह विचार स्पष्ट करता है। 

एक स्ट्रिंग की शुरुआत में सख्ती से मिलान करने के लिए और न केवल हर लाइन पर ( \n के बाद) आपको ^ और $ के बजाय \A और \Z का उपयोग करना होगा।

कैप्चर ग्रुप्स

कैप्चर ग्रुप्स के साथ, हम मिलान के एक हिस्से को कैप्चर कर सकते हैं और बाद में इसका पुन: उपयोग कर सकते हैं। मिलान को कैप्चर करने के लिए हम जिस हिस्से को कैप्चर करना चाहते हैं उसे पैरेंथेसिस में संलग्न करते हैं।

उदाहरण: लॉग फ़ाइल पार्स करना

Line = Struct.new(:time, :type, :msg)
LOG_FORMAT = /(\d{2}:\d{2}) (\w+) (.*)/
def parse_line(line)
  line.match(LOG_FORMAT) { |m| Line.new(*m.captures) }
end
parse_line("12:41 INFO User has logged in.")
# यह इस तरह के ऑब्जेक्ट्स उत्पन्न करता है:
# 

इस उदाहरण में, हम =~ के बजाय .match का उपयोग कर रहे हैं।

यह मेथड मिलान होने पर MatchData ऑब्जेक्ट लौटाता है, अन्यथा nil। MatchData क्लास में कई उपयोगी मेथड्स हैं, अधिक जानने के लिए डॉक्यूमेंटेशन देखें!

यदि आप केवल एक बूलियन मान (true / false) चाहते हैं तो आप match? मेथड का उपयोग कर सकते हैं, जो रूबी 2.4 से उपलब्ध है। यह match से भी तेज़ है क्योंकि रूबी को MatchData ऑब्जेक्ट बनाने की आवश्यकता नहीं है।

आप .captures मेथड का उपयोग करके या MatchData ऑब्जेक्ट को सरणी की तरह मानकर कैप्चर किए गए डेटा तक पहुंच सकते हैं, शून्य इंडेक्स में पूरा मिलान होगा और परिणामी इंडेक्स में मिलान ग्रुप्स होंगे।

यदि आप पहला कैप्चर ग्रुप चाहते हैं तो आप यह कर सकते हैं:

m = "John 31".match /\w+ (\d+)/
m[1] # 31 

आपके पास नॉन-कैप्चरिंग ग्रुप्स भी हो सकते हैं। वे आपको प्रदर्शन दंड के बिना अभिव्यक्तियों को एक साथ समूहित करने देंगे। आप नामित ग्रुप्स को जटिल अभिव्यक्तियों को पढ़ने में आसान बनाने के लिए उपयोगी पा सकते हैं।

सिंटैक्स विवरण
(?:...) नॉन-कैप्चरिंग ग्रुप
(?<foo>...) नामित ग्रुप

उदाहरण: नामित ग्रुप्स

m = "David 30".match /(?\w+) (?\d+)/
m[:age] # => "30"
m[:name] # => "David" 

एक नामित ग्रुप एक MatchData ऑब्जेक्ट लौटाता है जिसे आप परिणाम पढ़ने के लिए एक्सेस कर सकते हैं।

लुक अहेड और लुक बिहाइंड

यह एक अधिक उन्नत तकनीक है जो सभी रेगेक्स कार्यान्वयनों में उपलब्ध नहीं हो सकती। रूबी का रेगुलर एक्सप्रेशन इंजन यह करने में सक्षम है, तो आइए देखते हैं कि इसका लाभ कैसे उठाया जाए।

लुक अहेड हमें झांकने देता है और देखता है कि पहले या बाद में कोई विशिष्ट मिलान है या नहीं।

नाम विवरण
(?=pat) पॉजिटिव लुकअहेड
(?<=pat) पॉजिटिव लुकबिहाइंड
(?!pat) नेगेटिव लुकअहेड
(?<!pat) नेगेटिव लुकबिहाइंड

उदाहरण: क्या कम से कम एक अक्षर से पहले एक संख्या है?

def number_after_word?(str)
  !!(str =~ /(?<=\w) (\d+)/)
end
number_after_word?("Grade 99") 

रूबी की Regex क्लास

रूबी रेगुलर एक्सप्रेशन्स Regexp क्लास के इंस्टेंस हैं। ज्यादातर समय आप इस क्लास का सीधे उपयोग नहीं करेंगे, लेकिन यह जानना अच्छा है 🙂

puts /a/.class # Regexp 

एक संभावित उपयोग स्ट्रिंग से रेगेक्स बनाना है:

regexp = Regexp.new("a") 

रेगेक्स बनाने का एक और तरीका:

regexp = %r{\w+} 

रेगेक्स विकल्प

आप अपने रेगुलर एक्सप्रेशन पर कुछ विकल्प सेट कर सकते हैं ताकि यह अलग व्यवहार करे।

विकल्प विवरण
i रूबी रेगेक्स केस इन्सेंसिटिव
m डॉट नई लाइन से मेल खाता है
x व्हाइटस्पेस को नजरअंदाज करें

इन विकल्पों का उपयोग करने के लिए आप रेगेक्स के अंत में, क्लोजिंग / के बाद अक्षर जोड़ते हैं।

इस तरह:

"abc".match?(/[A-Z]/i) 

लंबे रेगुलर एक्सप्रेशन्स को फॉर्मेट करना

जटिल रूबी रेगुलर एक्सप्रेशन्स पढ़ने में काफी कठिन हो सकते हैं, इसलिए यदि हम उन्हें कई लाइनों में तोड़ दें तो यह मददगार होगा। हम 'x' मोडिफायर का उपयोग करके ऐसा कर सकते हैं। यह प्रारूप आपको अपने रेगेक्स के अंदर टिप्पणियों का उपयोग करने की भी अनुमति देता है।

उदाहरण:

LOG_FORMAT = %r{
  (\d{2}:\d{2}) # समय
  \s(\w+)       # इवेंट प्रकार
  \s(.*)        # संदेश
}x

रूबी रेगेक्स: इसे सभी को एक साथ रखना

रेगुलर एक्सप्रेशन्स का उपयोग कई रूबी मेथड्स के साथ किया जा सकता है।

  • .split
  • .scan
  • .gsub
  • और बहुत कुछ…

उदाहरण: .scan का उपयोग करके स्ट्रिंग से सभी शब्दों का मिलान करें

"this is some string".scan(/\w+/) # => ["this", "is", "some", "string"] 

उदाहरण: स्ट्रिंग से सभी संख्याएँ निकालें

"The year was 1492.".scan(/\d+/) # => ["1492"] 

उदाहरण: स्ट्रिंग में सभी शब्दों को कैपिटलाइज़ करें

str = "lord of the rings"
str.gsub(/\w+/) { |w| w.capitalize } # => "Lord Of The Rings" 

उदाहरण: ईमेल पते को मान्य करें

email = "test@example.com"
!!email.match(/\A[\w.+-]+@\w+\.\w+\z/) # true 

यह अंतिम उदाहरण परिणाम को बूलियन मान (true / false) में बदलने के लिए !! का उपयोग करता है, वैकल्पिक रूप से आप रूबी 2.4+ में match? मेथड का उपयोग कर सकते हैं जो आपके लिए यह पहले से करता है और यह तेज़ भी है।

निष्कर्ष

रेगुलर एक्सप्रेशन्स अद्भुत हैं लेकिन कभी-कभी वे थोड़े मुश्किल हो सकते हैं। Rubular.com जैसे टूल का उपयोग आपको रूबी रेगेक्स को अधिक इंटरैक्टिव तरीके से बनाने में मदद कर सकता है। Rubular में एक रूबी रेगुलर एक्सप्रेशन चीट शीट भी शामिल है जो आपको बहुत उपयोगी लगेगी। अब आपकी बारी है उस एडिटर को खोलने और कोडिंग शुरू करने की!

ओह, और अगर आपको यह पसंद आया तो इसे अपने दोस्तों के साथ शेयर करना न भूलें, ताकि अधिक लोग सीख सकें 🙂


  1. - JavaScript में किसी स्ट्रिंग के विरुद्ध रेगुलर एक्सप्रेशन का मिलान कैसे करें?

    अवलोकनJavaScript में match() मेथड का उपयोग करके किसी स्ट्रिंग के विरुद्ध रेगुलर एक्सप्रेशन का मिलान किया जाता है।पैरामीटरmatch(param) - एक रेगुलर एक्सप्रेशन ऑब्जेक्ट।उदाहरण<html>    <head>       <title>JavaScript String match() Method</title>   &

  1. JavaScript रेगुलर एक्सप्रेशन JavaScript रेगुलर एक्सप्रेशन

    रेगुलर एक्सप्रेशन कैरेक्टर्स की एक स्ट्रिंग है जो एक सर्च पैटर्न को दर्शाती है। इस सर्च पैटर्न का उपयोग यह निर्दिष्ट करने के लिए किया जाता है कि हम टेक्स्ट में क्या खोज रहे हैं।उदाहरण<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta

  1. जावास्क्रिप्ट रेगुलर एक्सप्रेशन्स में लुकबिहाइंड एसर्शन जावास्क्रिप्ट रेगुलर एक्सप्रेशन्स में लुकबिहाइंड एसर्शन

    परिचय लुकबिहाइंड एसर्शन (ES2018 में पेश) एक पैटर्न से तभी मिलान करने की अनुमति देता है जब उसके पहले कोई विशिष्ट पैटर्न मौजूद हो, बिना उस पूर्ववर्ती पैटर्न को मिलान में शामिल किए। यह दो प्रकार के होते हैं: पॉजिटिव लुकबिहाइंड (?<=...) और नेगेटिव लुकबिहाइंड (?<!...)। उदाहरण निम्न उदाहरण दर्शाता