मैं प्राक्षेपिक परीक्षण के बाहर रेगेक्स भाग की व्याख्या करूंगा: निम्नलिखित रेगेक्स, String s
जिसे दोहराते हुए String t
पाया जाता है, पाता है t
।
System.out.println(
"MamamiaMamamiaMamamia".replaceAll("^(.*)\\1+$", "$1")
); // prints "Mamamia"
जिस तरह से यह काम करता है वह यह है कि रेगेक्स कैप्चर करता (.*)
है \1
, और फिर देखता है कि क्या \1+
इसके पीछे है। ^
और का उपयोग करना$
यह सुनिश्चित करता है कि एक मैच पूरे स्ट्रिंग का होना चाहिए।
तो, एक तरह से, हमें दिया जाता है String s
, जो "बहु" है String t
, और रेगेक्स ऐसा t
(सबसे लंबा संभव है, क्योंकि \1
लालची है)।
एक बार जब आप समझ जाते हैं कि यह रेगेक्स क्यों काम करता है, तो (अब के लिए ओपी के रेक्स में पहले वैकल्पिक को अनदेखा करते हुए) यह समझाते हुए कि यह कैसे प्रायोगिक परीक्षण के लिए उपयोग किया जाता है, सरल है।
- की शुद्धता का परीक्षण करने के लिए
n
, पहले एक String
लंबाई n
(उसी के साथ भरा char
) उत्पन्न करें
- रेगेक्स
String
कुछ लंबाई (कहते हैं k
) को पकड़ता है \1
, और \1+
बाकी हिस्सों से मेल खाने की कोशिश करता हैString
- यदि कोई मैच होता है, तो
n
एक उचित मल्टीपल है k
, और इसलिए n
प्राइम नहीं है।
- यदि कोई मेल नहीं है, तो ऐसा कोई भी
k
मौजूद नहीं है जो विभाजित हो n
, और n
इसलिए एक प्रमुख है
.?|(..+?)\1+
अभाज्य संख्याओं का मिलान कैसे होता है ?
वास्तव में, यह नहीं है! यह मेल खाता है String
जिसकी लंबाई अभाज्य नहीं है!
.?
: String
लंबाई के प्रत्यावर्तन मैचों का पहला भाग 0
या 1
(परिभाषा द्वारा अभाज्य नहीं)
(..+?)\1+
: प्रत्यावर्तन के दूसरे भाग, regex की भिन्नता ऊपर बताया गया है, मैचों String
लंबाई की n
है कि एक के "एक बहु" String
लंबाई की k >= 2
(यानीn
एक समग्र, नहीं एक प्रमुख है)।
- ध्यान दें कि अनिच्छुक संशोधक
?
वास्तव में शुद्धता के लिए आवश्यक नहीं है, लेकिन यह k
पहले छोटे प्रयास करके प्रक्रिया को गति देने में मदद कर सकता है
बयान !
boolean
में पूरक ऑपरेटर पर ध्यान दें return
: यह नकारात्मक करता है matches
। यह तब होता है जब regex DOESN'T मैच होता है, n
अभाज्य है! यह एक दोहरा नकारात्मक तर्क है, इसलिए कोई आश्चर्य नहीं कि यह भ्रमित करने जैसा है !!
सरलीकरण
यहाँ इसे और अधिक पठनीय बनाने के लिए कोड का एक सरल पुनर्लेखन है:
public static boolean isPrime(int n) {
String lengthN = new String(new char[n]);
boolean isNotPrimeN = lengthN.matches(".?|(..+?)\\1+");
return !isNotPrimeN;
}
ऊपर मूल रूप से मूल जावा कोड के समान है, लेकिन तर्क को समझने में आसान बनाने के लिए स्थानीय चर के असाइनमेंट के साथ कई बयानों में टूट गया।
हम इस प्रकार है, परिमित पुनरावृत्ति का उपयोग करके, रेगेक्स को भी सरल बना सकते हैं:
boolean isNotPrimeN = lengthN.matches(".{0,1}|(.{2,})\\1+");
फिर से, एक String
लंबाई दी गई n
, उसी से भरा char
,
.{0,1}
जाँच करता है कि n = 0,1
नहीं, प्रधान नहीं
(.{2,})\1+
जाँच करता है कि n
क्या एक उचित एकाधिक k >= 2
, प्रमुख नहीं है
?
पर अनिच्छुक संशोधक के अपवाद के साथ \1
(स्पष्टता के लिए छोड़ दिया गया), उपरोक्त रेगेक्स मूल के समान है।
अधिक मज़ा रेगेक्स
निम्नलिखित रेगेक्स समान तकनीक का उपयोग करता है; यह शैक्षिक होना चाहिए:
System.out.println(
"OhMyGod=MyMyMyOhGodOhGodOhGod"
.replaceAll("^(.+)(.+)(.+)=(\\1|\\2|\\3)+$", "$1! $2! $3!")
); // prints "Oh! My! God!"
यह सभी देखें
!new String(new char[n]).matches(".?|(..+?)\\1+")
के बराबर है!((new String(new char[n])).matches(".?|(..+?)\\1+"))
।