डुप्लिकेट शब्दों के लिए नियमित अभिव्यक्ति


114

मैं एक नियमित अभिव्यक्ति नौसिखिया हूँ, और मैं यह नहीं जान सकता कि कैसे एक नियमित अभिव्यक्ति लिखने के लिए जो किसी भी डुप्लिकेट लगातार शब्दों को "मैच" करेगा जैसे:

में पेरिस वसंत।

ऐसा नहीं है कि संबंधित है।

तुम हंस क्यों रहे हो? क्या मेरी नियमित अभिव्यक्ति खराब हैं?

वहाँ एक नियमित अभिव्यक्ति है कि ऊपर बोल्ड तार के सभी मैच होगा?


4
@ पॉली: यह कोई "आरोप" नहीं था, लेकिन एक शांत, सामान्य सवाल है जो पूरी तरह से एक जवाब के रूप में "नहीं" ले सकता है। @ जोशुआ: हां, कुछ लोग (बहुत कम नहीं) इस साइट को उनके लिए अपना होमवर्क करने देते हैं। लेकिन होमवर्क के सवाल पूछना एसओ पर बुरा नहीं है, जब उन्हें इस तरह से टैग किया जाता है। आमतौर पर उत्तरों की शैली "यहां समाधान है" से "यहां कुछ चीजें हैं जिनके बारे में आपने नहीं सोचा है" में परिवर्तन होता है, और यह एक अच्छी बात है। किसी को भेद करने की कोशिश करनी होगी, उसके मामले में यह मैं था, और कहीं और "अन्य लोग" ऐसा ही करते हैं। बस इतना ही।
तोमलक

13
आशा है कि "प्रश्न की तरह यह कार्यस्थल प्रश्न की तरह थोड़ा सा लगता है। यह है?" और फिर लोग बहस करेंगे कि क्या स्टैक ओवरफ्लो किसी का काम कर रहा है।
मार्सियो

@ जोशुआ +1 आपके द्वारा स्वीकार किए गए रेगेक्स समाधान के संबंध में, क्या आप मुझे बता सकते हैं कि मैं जोड़ी के एक तत्व द्वारा मैचों (डुप्लिकेट) को कैसे बदल सकता हूं (जैसे, not that that is related-> not that is related)? अग्रिम धन्यवाद
एंटोनी

@ जोशुआ मुझे लगता है कि मुझे इसका हल मिल गया है: मुझे इसकी जगह लेनी चाहिए \1!
एंटोनी

2
@DavidLeal कैसे \b(\w+)\s+(\1\s*)+\b?
यतु

जवाबों:


141

इस नियमित अभिव्यक्ति का प्रयास करें:

\b(\w+)\s+\1\b

यहां \bएक शब्द सीमा है और \1पहले समूह के कैप्चर किए गए मैच का संदर्भ है।


1
मुझे आश्चर्य है; क्या यह भी संभव \0है? (जहां \0पूरा रेगेक्स है, वर्तमान बिंदु तक या जहां \0पूरे रेगेक्स को संदर्भित करता है)
पिंडातजुह

@Pindatjuh: नहीं, मुझे ऐसा नहीं लगता क्योंकि यह उप-मैच भी पूरे मैच का हिस्सा होगा।
गंबू 3

एक्लिप्स खोज / प्रतिस्थापित संवाद में प्रयुक्त रेगेक्स इंजन पर कम से कम काम करता है।
Chaos_99

3
बस एक चेतावनी, यह एपोस्ट्रोफस या (नोएल उल्लेख के रूप में) शब्द के साथ संभाल नहीं करता है। इन मामलों में माइक का समाधान बेहतर काम करता है

3
इसके अलावा, यह ट्रिप्लिकेट्स (या अधिक) को नहीं पकड़ेगा, न कि जब डुप्लिकेट / ट्रिपलप्लेट में से एक स्ट्रिंग के अंत में हो
Nico

20

मेरा मानना ​​है कि यह रेगेक्स अधिक स्थितियों को संभालता है:

/(\b\S+\b)\s+\b\1\b/

टेस्ट स्ट्रिंग्स का एक अच्छा चयन यहां पाया जा सकता है: http://callumacrae.github.com/regex-tuesday/challenge1.html


महान, apostrophes / हाइफ़न / आदि के साथ काम करता है। भी - धन्यवाद!

चुनौती 1 लिंक के लिए, आप समूहीकृत शब्द का उपयोग करने के लिए प्रतिस्थापित क्षेत्र में क्या रखते हैं? कोशिश की <strong>\0</strong>लेकिन काम नहीं आया।
20

2
यह ट्रिप्लिकेट्स (या अधिक) को नहीं पकड़ेगा, न कि जब डुप्लिकेट / ट्रिपलेट में से एक स्ट्रिंग के अंत में होगा
निको

@ गुप्तचर आप उपयोग करना चाहते हैं $1 <strong>$2</strong>। लेकिन विभिन्न रेगेक्स का भी उपयोग करें /\b(\S+) (\1)\b/gi। यहाँ एक लिंक है: callumacrae.github.io/regex-tuesday/…
dsalaj

और अगर मैं किसी विशेष टैग से लगातार सभी शब्द ढूंढना चाहता हूं, जैसे <p class="bebe">bla bla</p>कि मैं इस रेगेक्स फॉर्मूला को कैसे एकीकृत कर सकता हूं?
जस्ट मी

7

नीचे आरई के साथ यह कोशिश करो

  • शब्द सीमा का \ b प्रारंभ
  • \ W + कोई भी शब्द वर्ण
  • \ 1 समान शब्द पहले से मेल खाता है
  • शब्द का \ b अंत
  • () * फिर से दोहराना

    public static void main(String[] args) {
    
        String regex = "\\b(\\w+)(\\b\\W+\\b\\1\\b)*";//  "/* Write a RegEx matching repeated words here. */";
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE/* Insert the correct Pattern flag here.*/);
    
        Scanner in = new Scanner(System.in);
    
        int numSentences = Integer.parseInt(in.nextLine());
    
        while (numSentences-- > 0) {
            String input = in.nextLine();
    
            Matcher m = p.matcher(input);
    
            // Check for subsequences of input that match the compiled pattern
            while (m.find()) {
                input = input.replaceAll(m.group(0),m.group(1));
            }
    
            // Prints the modified sentence.
            System.out.println(input);
        }
    
        in.close();
    }

5

व्यापक रूप से इस्तेमाल PCRE पुस्तकालय ऐसी स्थितियों (आप को प्राप्त नहीं होगा संभाल कर सकते हैं , हालांकि POSIX अनुरूप regex इंजन के साथ एक ही):

(\b\w+\b)\W+\1

आपको दो शब्दों के बीच के पात्रों को मिलाने के लिए कुछ चाहिए , जैसे \W+\bयह नहीं करेंगे, क्योंकि यह किसी भी वर्ण का उपभोग नहीं करता है।
एलन मूर

यह संभावित रूप से झूठे-सकारात्मक मिलान जैसे मामलों में परिणाम देगा ... the these problems...। यह समाधान गम्बो के पैटर्न की सामान्य संरचना के रूप में विश्वसनीय नहीं है जो शब्द सीमाओं को पर्याप्त रूप से लागू करता है।
मिकमैकुसा

और अगर मैं किसी विशेष टैग से लगातार सभी शब्द ढूंढना चाहता हूं, जैसे <p class="bebe">bla bla</p>कि मैं इस रेगेक्स फॉर्मूला को कैसे एकीकृत कर सकता हूं?
जस्ट मी

4

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

(\S+\s*)\1{2,}

(\S+\s*) वर्णों के किसी भी स्ट्रिंग के लिए लग रहा है कि व्हाट्सएप नहीं है, उसके बाद व्हाट्सएप।

\1{2,}फिर स्ट्रिंग में मिलान करने के लिए उस वाक्यांश के 2 से अधिक उदाहरणों की तलाश करता है। यदि 3 वाक्यांश हैं जो समान हैं, तो यह मेल खाता है।


यह उत्तर भ्रामक है। यह डुप्लिकेट का शिकार नहीं करता है, यह 3 या अधिक घटनाओं के साथ सबस्ट्रिंग का शिकार करता है। \s*कब्जा समूह में होने के कारण यह बहुत मजबूत भी नहीं है । इस प्रदर्शन को देखें: regex101.com/r/JtCdd6/1
mickmackusa

इसके अलावा चरम मामले (कम-आवृत्ति पाठ) झूठे सकारात्मक मैचों का उत्पादन करेंगे। उदाहरण के लिए I said "oioioi" that's some wicked mistressship!पर oioioiऔरsss
mickmackusa

4

किसी भी संख्या में लगातार शब्दों को खोजने के लिए नीचे दी गई अभिव्यक्ति को सही ढंग से काम करना चाहिए। मिलान असंवेदनशील हो सकता है।

String regex = "\\b(\\w+)(\\s+\\1\\b)*";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

Matcher m = p.matcher(input);

// Check for subsequences of input that match the compiled pattern
while (m.find()) {
     input = input.replaceAll(m.group(0), m.group(1));
}

नमूना इनपुट: अलविदा गुडबाय गूडबी

नमूना आउटपुट: अलविदा

स्पष्टीकरण:

रेगेक्स अभिव्यक्ति:

\ b: एक शब्द सीमा की शुरुआत

\ w +: शब्द वर्णों की कोई भी संख्या

(\ _ s + 1 + b) *: किसी भी स्थान का शब्द के बाद का स्थान जो पिछले शब्द से मेल खाता है और शब्द सीमा समाप्त करता है। * में लिपटी हुई पूरी चीज़ एक से अधिक दोहराव खोजने में मदद करती है।

समूहीकरण:

m.group (0): उपरोक्त मामले में मेल खाता समूह गुडबाय अलविदा GooDbYe

m.group (1): उपरोक्त मामले गुडबाय में मिलान पैटर्न का पहला शब्द होगा

बदलें विधि शब्द के पहले उदाहरण के साथ सभी लगातार मिलान किए गए शब्दों को बदल देगी।


3

नहीं। यह एक अनियमित व्याकरण है। इंजन हो सकता है- / भाषा-विशिष्ट नियमित अभिव्यक्ति जो आप उपयोग कर सकते हैं, लेकिन कोई सार्वभौमिक नियमित अभिव्यक्ति नहीं है जो ऐसा कर सकती है।


12
हालांकि एक सख्त अर्थ में सही होने के नाते, मेरा मानना ​​है कि अब गंभीर उपयोग में कोई रेगेक्स इंजन नहीं है जो समूह और बैक-रेफरेंस का समर्थन नहीं करता है।
तोमलक

3

यहाँ एक है जो कई बार कई शब्द पकड़ता है:

(\b\w+\b)(\s+\1)+

और अगर मैं किसी विशेष टैग से लगातार सभी शब्द ढूंढना चाहता हूं, जैसे <p class="bebe">bla bla</p>कि मैं इस रेगेक्स फॉर्मूला को कैसे एकीकृत कर सकता हूं?
जस्ट मी

मुझे विश्वास है कि HTML पार्सिंग की आवश्यकता होगी। किसी भी दिए गए टैग के लिए जिसे आप खोजना चाहते हैं, HTML के अंदर सभी टैग घटनाएँ खोजें, और इस रेगेक्स को एक-एक करके एक-एक करके चलाएं। या यदि आप इस बात की परवाह नहीं करते हैं कि HTML में पुनरावृत्ति कहां होती है, सभी टैग पाठ विशेषताओं को
संक्षिप्त करें और संक्षिप्त

मैं खुद को इसका जवाब देता हूं<p class="bebe">.*?\b\s+(\w+)\b\K\s+\1\s+\b(?=.*?<\/p>)
जस्ट मी

3

Regex to Strip 2+ डुप्लिकेट शब्द (लगातार / गैर-लगातार शब्द)

इस regex को आज़माएं जो 2 या अधिक डुप्लिकेट शब्दों को पकड़ सकता है और केवल एक ही शब्द को पीछे छोड़ सकता है। और डुप्लिकेट शब्दों को भी लगातार होने की आवश्यकता नहीं है

/\b(\w+)\b(?=.*?\b\1\b)/ig

यहां, \bवर्ड बाउंड्री के ?=लिए उपयोग किया जाता है, सकारात्मक लुकहेड के लिए उपयोग किया जाता है, और \1बैक- रेफ़रिंग के लिए उपयोग किया जाता है।

उदाहरण स्रोत


1
गैर-लगातार एक बुरा विचार है: "the cat sat on the mat"->" cat sat on the mat"
वाल्फ

@ सच। फिर भी, ऐसे परिदृश्य हैं जहां यह इरादा है। (उदाहरण के लिए: डेटा स्क्रैप करते हुए)
निकेत पाठक

मैंने इसे ठीक करने के बाद आप अपने रेगेक्स को फिर से क्यों तोड़ेंगे ? क्या आपको लगा कि मैंने इसका इरादा बदल दिया है? आपके द्वारा लिंक किए गए उदाहरण में भी गलती नहीं है।
वॉलफ

हां, यह एक गलती थी, नकल ने गलत सामान चिपका दिया। वास्तव में मेरे उदाहरण से एक की नकल करने का इरादा है। वैसे भी, अब यह काम करता है! इतना अच्छा! धन्यवाद!
निकेत पाठक

2

जावास्क्रिप्ट में उदाहरण: अच्छे भागों को ऐसा करने के लिए अनुकूलित किया जा सकता है:

var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;

\ b शब्द सीमाओं के लिए \ w का उपयोग करता है, जहां \ w [0-9A-Z_a-z] के बराबर है। यदि आपको उस सीमा पर कोई आपत्ति नहीं है, तो स्वीकृत उत्तर ठीक है।


2

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

पैटर्न: /(\b\S+)(?:\s+\1\b)+/( पैटर्न डेमो )
बदलें: $1(फुलस्ट्रिंग मैच को कैप्चर ग्रुप # 1 से बदल देता है)

यह पैटर्न लालच में एक "पूरे" गैर-व्हाट्सएप प्रतिस्थापन से मेल खाता है, फिर मिलान किए गए प्रतिस्थापन की एक या एक से अधिक प्रतियों की आवश्यकता होती है, जिसे एक या अधिक व्हाट्सएप वर्णों (स्थान, टैब, न्यूलाइन, आदि) द्वारा सीमांकित किया जा सकता है।

विशेष रूप से:

  • \b (शब्द सीमा) अक्षर यह सुनिश्चित करने के लिए महत्वपूर्ण हैं कि आंशिक शब्द मेल नहीं खाते हैं।
  • दूसरा पैतृक एक गैर-कैप्चरिंग समूह है, क्योंकि इस चर चौड़ाई के विकल्प को कैप्चर करने की आवश्यकता नहीं है - केवल मिलान / अवशोषित।
  • +(एक या अधिक परिमाणक) गैर पर कब्जा समूह पर की तुलना में अधिक उचित है *क्योंकि *कब्जा करने के लिए regex इंजन "परेशान" और घटनाओं सिंगलटन का स्थान ले लेगा - यह बेकार पैटर्न डिजाइन है।

* ध्यान दें कि यदि आप विराम चिह्न के साथ वाक्यों या इनपुट स्ट्रिंग्स के साथ काम कर रहे हैं, तो पैटर्न को और अधिक परिष्कृत करने की आवश्यकता होगी।


@AadJones आपके php प्रोजेक्ट में इस पैटर्न का उपयोग करता है। निको के उत्तर में कुछ अनावश्यक वाक्य रचना है।
मिकमैकुसा

1

यह अभिव्यक्ति (माइक से ऊपर, प्रेरित) सभी डुप्लिकेट, ट्रिप्लिकेट्स, आदि को पकड़ने के लिए लगता है, जिसमें स्ट्रिंग के अंत में शामिल हैं, जो अन्य नहीं करते हैं:

/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")

मुझे पता है कि प्रश्न केवल डुप्लिकेट से मिलान करने के लिए कहा गया था , लेकिन एक ट्रिपलेट केवल एक दूसरे के बगल में 2 डुप्लिकेट है :)

पहले, मैंने (^|\s+)यह सुनिश्चित करने के लिए कहा कि यह एक पूर्ण शब्द से शुरू होता है, अन्यथा "बच्चे का स्टेक" "चाइल्डस्टीक" ("s" का मिलान होगा) जाएगा। फिर, यह सभी पूर्ण शब्दों ( (\b\S+\b)) से मेल खाता है , इसके बाद स्ट्रिंग का अंत ( $) या कई स्थान ( \s+), पूरे एक से अधिक बार दोहराया जाता है।

मैंने इसे इस तरह आज़माया और इसने अच्छा काम किया:

var s = "here here here     here is ahi-ahi ahi-ahi ahi-ahi joe's joe's joe's joe's joe's the result result     result";
print( s.replace( /(\b\S+\b)(($|\s+)\1)+/g, "$1"))         
--> here is ahi-ahi joe's the result

मुझे PHP में इसे फिर से लिखने में परेशानी हो रही है, यह महत्वपूर्ण है कि मैं डुप्लिकेट / ट्रिपलीकेट्स आदि की प्रत्येक घटना की जगह मेल खाने वाले डुप्लिकेट की एक प्रति प्राप्त करता हूं। अब तक मेरे पास: preg_replace ('/ (^ | \ s +) (\ S +) (| ($ | \ s +) \ 2) + / im ',' $ 0 ', $ स्ट्रिंग);
एडमजोन

यह सबसे अच्छा जवाब है। मैं बस \bअंत में इस तरह से जोड़कर एक बदलाव किया : /(^|\s+)(\S+)(($|\s+)\2)+\b/g, "$1$2")यह तो इस तरह की स्थितियों के लिए काम the the string String string stringing the the along the the stringकरेंगे : the string stringing the along the stringसूचना बन जाएगा string stringing। यह आपके उत्तर के साथ मेल खाता है। धन्यवाद।
Ste

-1

यदि आप डुप्लिकेट शब्दों के लिए केस-असंवेदनशील जाँच चाहते हैं, तो इसका उपयोग करें।

(?i)\\b(\\w+)\\s+\\1\\b

केस-असंवेदनशील पैटर्न संशोधक का उपयोग करना आपके पैटर्न के लिए कोई उपयोग नहीं है। झंडे के प्रभाव के लिए कोई पत्र सीमा नहीं है।
मिकमैकुसा

यह प्रभावी रूप से स्वीकृत उत्तर की एक डुप्लिकेट है और पृष्ठ पर कोई मूल्य नहीं जोड़ता है। कृपया पेज ब्लोट को कम करने के लिए इस उत्तर को हटाने पर विचार करें।
मिकमैकुसा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.