2008-10-07 16 views
23

मैं एक रेगेक्स की तलाश में हूं जो दोहराए गए अक्षरों को मिलेगा। तो कोई पत्र दो या उससे अधिक, उदाहरण के लिए:मैं पर्ल रेगेक्स के साथ दोहराए गए अक्षरों को कैसे ढूंढ सकता हूं?

booooooot or abbott 

मुझे वह पत्र नहीं पता जो मैं समय से पहले देख रहा हूं।

यह एक सवाल है जिसे साक्षात्कार में मुझसे पूछा गया था और फिर साक्षात्कार में पूछा गया था। इतने सारे लोग इसे सही नहीं पाते हैं।

उत्तर

52

आप किसी भी पत्र प्राप्त कर सकते हैं, तो का उपयोग एक ही पत्र को दूसरी बार (या अधिक) ढूंढने के लिए। अगर आपको केवल पत्र जानने की जरूरत है, तो $1 इसमें शामिल होगा। अन्यथा आप दूसरे मैच को पहले पर जोड़ सकते हैं।

my $str = "Foooooobar"; 

$str =~ /(\w)(\1+)/; 

print $1; 
# prints 'o' 
print $1 . $2; 
# prints 'oooooo' 
+0

केवल अक्षरों के लिए [ए-जेए-जेड] के लिए \ w स्वैप आउट करें। – TomC

+4

@TomC: यह यूनिकोड सुरक्षित नहीं है! –

+0

अब मैं केवल एक के लिए दोगुनी अक्षरों को प्रतिस्थापित कर सकता हूं: Regex.Replace (str, @ "(\ w) \ 1+", "$ 1"); धन्यवाद एडम। –

6

उपयोग \ N पिछले समूहों का उल्लेख करने के:

/(\w)\1+/g 
0

कैसे के बारे में:

(\w)\1+ 

पहले भाग में एक चरित्र के आसपास एक अनाम समूह बनाता है, फिर वापस-संदर्भ है कि एक ही के लिए लग रहा है चरित्र।

+0

यह केवल दो दोहराव वाले वर्णों से मेल खाता है, न कि पूरे दोहराव वाले सबस्ट्रिंग। [ए-जेए-जेड] के बजाय –

9

मैं एक backreference का उपयोग कर काम करेंगे के बारे में सोचो:

(\w)\1+ 

\w मूल रूप से [a-zA-Z_0-9] इसलिए यदि आप केवल एक और जेड (मामले insensitively) के बीच पत्र का मिलान करना चाहते, [a-zA-Z] बजाय का उपयोग करें।

(संपादित करें: या, Tanktalus की तरह अपने टिप्पणी (और दूसरों के रूप में अच्छी तरह से जवाब दे दिया है के रूप में),[[:alpha:]]है, जो वातावरण के प्रति संवेदनशील है में उल्लेख किया है) \1

+0

, बस [[: अल्फा:]] का उपयोग करें जो लोकेल-संवेदनशील है ;-) – Tanktalus

14

मुझे लगता है कि आप वास्तव में नहीं बल्कि "\ डब्ल्यू" की तुलना में इस चाहते हैं कि के रूप में संख्या और अंडरस्कोर भी शामिल है।

([a-zA-Z])\1+ 

ठीक है, ठीक है, मैं एक संकेत लियोन ले सकता हूं। यूनिकोड-दुनिया या पॉज़िक्स सामान के लिए इसका इस्तेमाल करें।

([[:alpha:]])\1+ 
+2

हम एक यूनिकोड दुनिया में रहते हैं। [ए-जेए-जेड] अधिकांश भाषाओं को कवर नहीं करेगा। [[: अल्फा:]] और अधिक सही होगा। –

+0

ओह आप पागल विदेशियों! ; ओ) हाँ, गैर-अमेरिकी अंग्रेजी वर्णों के लिए यूनिकोड बेहतर वाक्यविन्यास होगा। – Keng

4

आप शायद एक पत्र माना जाता है, और यह आपके लोकेल पर निर्भर करता है। आईएसओ लैटिन -1 का उपयोग करने से उच्चारण किए गए पश्चिमी भाषा के अक्षरों को अक्षरों के रूप में मिलान करने की अनुमति मिल जाएगी। निम्नलिखित कार्यक्रम में, डिफ़ॉल्ट स्थान é को नहीं पहचानता है, और इस तरह क्री मिलान करने के लिए विफल रहता है। लोकेल सेटिंग कोड को असम्बद्ध करें, और उसके बाद यह मिलान करना शुरू हो जाता है।

भी ध्यान रखें कि \ w अंक और सभी पत्र के साथ-साथ अंडरस्कोर वर्ण भी शामिल है। केवल अक्षरों को पाने के लिए, आपको गैर-अल्फानम, अंक और अंडरस्कोर वर्णों का पूरक लेने की आवश्यकता है। यह केवल पत्र छोड़ देता है।

कि समझना आसान सवाल "क्या नियमित अभिव्यक्ति 3 को छोड़कर किसी भी अंकों से मेल खाता है?" के रूप में यह तैयार करने से हो सकता है, और जवाब है/[^ \ डी 3] /।

#! /usr/local/bin/perl 

use strict; 
use warnings; 

# uncomment the following three lines: 
# use locale; 
# use POSIX; 
# setlocale(LC_CTYPE, 'fr_FR.ISO8859-1'); 

while (<DATA>) { 
    chomp; 
    if (/([^\W_0-9])\1+/) { 
     print "$_: dup [$1]\n"; 
    } 
    else { 
     print "$_: nope\n"; 
    } 
} 

__DATA__ 
100 
food 
créé 
a::b 
3

निम्नलिखित कोड दो अक्षर या दो बार दोहराए जाने वाले सभी पात्रों को वापस कर देगा।

मेरा $ str = "SSSannnkaaarsss";

प्रिंट $ str = ~/(\ w) \ 1 +/g;

1

नियमित रूप से अभिव्यक्तियों का परीक्षण करने के लिए एक असली आसान मुफ्त साइट RegExBuddy से FYI RegExr at gskinner.com है। अच्छी तरह से ([[:alpha:]])(\1+) संभालती है।

2
बस किक के लिए

, एक पूरी तरह से अलग दृष्टिकोण:

if (($str^substr($str,1)) =~ /\0+/) { 
    print "found ", substr($str, $-[0], $+[0]-$-[0]+1), " at offset ", $-[0]; 
} 
+0

हां, यह गैर अक्षरों को भी मिलेगा। लेकिन क्या आप सूक्ष्म बग पा सकते हैं? – ysth

0

मुझे लगता है कि यह होना चाहिए भी काम करते हैं:

((\w)(?=\2))+\2

0
/(.)\\1{2,}+/u 

'यू' संशोधक यूनिकोड के साथ मिलान

संबंधित मुद्दे