रेगुलर एक्सप्रेशन स्ट्रिंग्स को पैटर्न मैच करने का एक बहुत बहुमुखी तरीका हैं, जिनके लिए इसी काम के लिए बनाई गई एक डोमेन स्पेसिफिक लैंग्वेज (DSL) इस्तेमाल होती है।
कई अन्य प्रोग्रामिंग भाषाओं की तरह Julia अपनी खुद की रेगेक्स लाइब्रेरी बनाने की कोशिश नहीं करती। इसके बजाय यह लोकप्रिय PCRE2 लाइब्रेरी के ऊपर बनाई गई है, जिससे ऐसा रेगेक्स सिंटैक्स मिलता है जो बिल्कुल (उदाहरण के लिए) Gleam जैसा और Javascript से बहुत मिलता-जुलता है।
यह Julia सिलेबस मान लेता है कि आप बुनियादी रेगेक्स सिंटैक्स से पहले से परिचित हैं। हम केवल Julia से जुड़ी खास बातों पर ध्यान देंगे।
आपके रेगुलर एक्सप्रेशन के ज्ञान को ताज़ा करने के लिए कुछ संसाधन नीचे दिए गए हैं।
रेगुलर एक्सप्रेशन के लिए Julia का इंटरफ़ेस मैनुअल में बताया गया है।
Julia में एक रेगुलर एक्सप्रेशन बस एक ऐसी स्ट्रिंग होती है जिसके शुरुआती " से ठीक पहले r लिखा होता है। सारी बुनियादी कार्यक्षमता स्टैंडर्ड लाइब्रेरी का हिस्सा है।
दरअसल, Strings कॉन्सेप्ट में पहले ही चर्चा किए गए कई फंक्शन शुरू से ही रेगेक्स खोजों के लिए बने हैं, जैसे occursin().
julia> re = r"test$"
r"test$"
julia> typeof(re)
Regex
# Does a string end with "test"?
julia> occursin(re, "this is a test")
true
julia> occursin(re, "these are tests")
false
बंद करने वाले कोट के बाद मॉडिफायर अक्षर आ सकते हैं, जैसे केस-असंवेदनशील मैच के लिए i.
julia> occursin(r"test", "Testing")
false
julia> occursin(r"test"i, "Testing")
true
आम तौर पर हम जानना चाहते हैं कि क्या मैच हुआ। इसके लिए रेगेक्स के अंदर ब्रैकेट में कैप्चर ग्रुप डाले जाते हैं और फिर match() फंक्शन इस्तेमाल किया जाता है।
julia> m = match(r"(\d+g) .* (\d+ml)", "dissolve 25g sugar in 200ml water")
RegexMatch("25g sugar in 200ml", 1="25g", 2="200ml")
julia> m.captures
2-element Vector{Union{Nothing, SubString{String}}}:
"25g"
"200ml"
# how many matches?
julia> length(m.captures)
2
# what matched?
julia> m[1], m[2]
("25g", "200ml")
# Starting positions of the matches (character index)
julia> m.offsets
2-element Vector{Int64}:
10
23
बेशक, मैच असफल भी हो सकते हैं। तब नतीजा RegexMatch के बजाय खास वैल्यू Nothing होता है, इसलिए इसकी जाँच के लिए तैयार रहिए।
# failed match
m = match(r"(not here)", "dissolve 25g sugar in 200ml water")
julia> typeof(m)
Nothing
julia> isnothing(m)
true
हालाँकि match डिफ़ॉल्ट रूप से स्ट्रिंग की शुरुआत से खोजना शुरू करता है, हम पहले n अक्षरों को छोड़ने के लिए एक ऑफसेट n भी दे सकते हैं।
# capture first match
julia> m = match(r"(\wat)", "cat, sat, mat")
RegexMatch("cat", 1="cat")
# ignore first 5 characters, then match
julia> m = match(r"(\wat)", "cat, sat, mat", 5)
RegexMatch("sat", 1="sat")
Julia में match() लक्ष्य स्ट्रिंग के अंदर केवल पहला मैच ढूँढता है: कुछ अन्य भाषाओं की तरह इसका कोई ग्लोबल मॉडिफायर नहीं है।
इसके बजाय हमारे पास eachmatch() है, जो मैचों का इटरेटर लौटाता है। इसका मूल्यांकन तभी होता है जब ज़रूरत पड़े, इसलिए आपको इसे अपने मनचाहे रूप में बदलना पड़ सकता है।
julia> matches = eachmatch(r"(\wat)", "cat, sat, mat")
Base.RegexMatchIterator{String}(r"(\wat)", "cat, sat, mat", false)
# convert to vector
julia> collect(matches)
3-element Vector{RegexMatch}:
RegexMatch("cat", 1="cat")
RegexMatch("sat", 1="sat")
RegexMatch("mat", 1="mat")
# convert with comprehension
julia> [m.match for m in matches]
3-element Vector{SubString{String}}:
"cat"
"sat"
"mat"
# broadcast an anonymous function
julia> (m -> m.match).(matches)
3-element Vector{SubString{String}}:
"cat"
"sat"
"mat"
डिफ़ॉल्ट रूप से ओवरलैपिंग मैच की अनुमति नहीं होती। इसे बदलने के लिए overlap = true को कीवर्ड आर्गुमेंट के रूप में जोड़िए।
julia> eachmatch(r"aba", "abababa") |> collect # matches at positions 1, 5
2-element Vector{RegexMatch}:
RegexMatch("aba")
RegexMatch("aba")
julia> eachmatch(r"aba", "abababa"; overlap = true) |> collect # also matches at position 3
3-element Vector{RegexMatch}:
RegexMatch("aba")
RegexMatch("aba")
RegexMatch("aba")
रेगेक्स इस्तेमाल करने की एक आम वजह मैच को किसी दूसरी स्ट्रिंग से बदलना है।
replace() फंक्शन की चर्चा Strings कॉन्सेप्ट में हो चुकी है, जहाँ खोज के लिए स्ट्रिंग लिटरल इस्तेमाल किए जाते थे। यही फंक्शन रेगेक्स मैचिंग की पूरी शक्ति का उपयोग भी कर सकता है।
julia> replace("some string", r"[aeiou]" => "*")
"s*m* str*ng"
julia> replace("first second", r"(\w+) (?<agroup>\w+)" => s"\g<agroup> \1")
"second first"
ऊपर का दूसरा उदाहरण दिखाता है कि एक s" " स्ट्रिंग के अंदर बदलाव में क्रमांकित और नामित, दोनों तरह के कैप्चर ग्रुप कैसे इस्तेमाल किए जा सकते हैं।
अधिक जानकारी के लिए मैनुअल देखिए: यह ऐसा विषय है जो अधिकांश प्रोग्रामरों को बार-बार डॉक्यूमेंटेशन पर लौटने को मजबूर कर देता है!