रेगेक्स का उपयोग करके एक विकल्प को कैसे निकालना है


382

मेरे पास एक स्ट्रिंग है जिसमें दो एकल उद्धरण हैं, 'चरित्र। एकल उद्धरणों के बीच में वह डेटा है जो मुझे चाहिए।

मैं निम्नलिखित पाठ से "डेटा मैं चाहता हूं" निकालने के लिए एक रेगेक्स कैसे लिख सकता हूं?

mydata = "some string with 'the data i want' inside";

जवाबों:


569

यह मानते हुए कि आप एकल उद्धरणों के बीच का भाग चाहते हैं, इस नियमित अभिव्यक्ति का उपयोग करें Matcher:

"'(.*?)'"

उदाहरण:

String mydata = "some string with 'the data i want' inside";
Pattern pattern = Pattern.compile("'(.*?)'");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find())
{
    System.out.println(matcher.group(1));
}

परिणाम:

डेटा मुझे चाहिए

12
लानत है .. मैं हमेशा गैर लालची संशोधक के बारे में भूल जाता हूँ :(
Mihai Toader

33
जब आप एक से अधिक घटनाओं की अपेक्षा करते हैं, तो "अगर" को "एक" से बदलें
OneWorld

14
काम करने के लिए इस कोड नमूने के लिए matcher.find () की आवश्यकता है। इस विधि को कॉल करने में विफल होने के परिणामस्वरूप matcher.group (1) कहा जाता है, तो "कोई मैच नहीं मिला" अपवाद होगा।
14

25
@mFontoura समूह (0) बाहरी '' के साथ पूरा मैच लौटाएगा। समूह (1) '' '' के बिना '' के बीच जो है, उसे स्वयं लौटाता है।
tagy22

6
@ यह देर से जवाब है, लेकिन? इस मामले में गैर-लालची संशोधक है, ताकि this 'is' my 'data' with quotesयह जल्दी बंद isहो जाए और अधिक से अधिक पात्रों के मिलान के बजाय वापस आ जाए और वापस लौट आए is' my 'data, जो कि डिफ़ॉल्ट व्यवहार है।
टाइमकिलर

68

इसके लिए आपको regex की आवश्यकता नहीं है।

Apache commons lang को अपनी परियोजना में शामिल करें ( http://commons.apache.org/proper/commons-lang/ ), तो निम्न कार्य करें:

String dataYouWant = StringUtils.substringBetween(mydata, "'");

12
आपको यह ध्यान रखना होगा कि आपका सॉफ्टवेयर कैसे वितरित किया जाएगा। यदि यह एक वेबस्टार्ट जैसा कुछ है, तो यह केवल एक कार्यक्षमता का उपयोग करने के लिए अपाचे कॉमन्स को जोड़ना बुद्धिमानी नहीं है। लेकिन शायद यह नहीं है। अपाचे कॉमन्स के अलावा भी बहुत कुछ है। यहां तक ​​कि कठिन है कि रेगेक्स को जानना अच्छा है, आपको इसका उपयोग करने के समय सावधानी बरतनी चाहिए। Regex को पढ़ना, लिखना और डीबग करना वास्तव में कठिन हो सकता है। इसका उपयोग करते हुए कुछ संदर्भ बेहतर समाधान हो सकते हैं।
बीथोर्न

3
कभी-कभी StringUtils पहले से ही होता है, उन मामलों में यह समाधान बहुत क्लीनर और पठनीय है।
गागोर नेगी

7
5 मील (जब आप एक वर्ष में केवल एक बार यात्रा कर रहे हैं) यात्रा करने के लिए कार खरीदना पसंद है।
प्रयागपाद 01

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

14
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile(".*'([^']*)'.*");
        String mydata = "some string with 'the data i want' inside";

        Matcher matcher = pattern.matcher(mydata);
        if(matcher.matches()) {
            System.out.println(matcher.group(1));
        }

    }
}

2
Println (matcher.group (0)); <--- शून्य आधारित सूचकांक
nclord

4
संख्या समूह (0) का विशेष अर्थ है, समूहों को कैप्चर करना सूचकांक समूह (1) पर शुरू होता है (यानी समूह (1) उत्तर में सही है)। "कैप्चरिंग समूहों को बाएं से दाएं अनुक्रमित किया जाता है, जो एक पर शुरू होता है। समूह शून्य पूरे पैटर्न को दर्शाता है" - स्रोत: docs.oracle.com/javase/8/docs/api/java/util/regex/…
Apriori

12

इसके लिए एक साधारण लाइनर है:

String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1");

मिलान समूह को वैकल्पिक बनाने से, यह उस मामले में रिक्त वापस आने से उद्धरण के लिए भी पूरा नहीं होता है।

देखें लाइव डेमो


10

क्योंकि आपने स्केला को भी टिक किया है, रेगेक्स के बिना एक समाधान जो कई उद्धृत स्ट्रिंग्स के साथ आसानी से निपटता है:

val text = "some string with 'the data i want' inside 'and even more data'"
text.split("'").zipWithIndex.filter(_._2 % 2 != 0).map(_._1)

res: Array[java.lang.String] = Array(the data i want, and even more data)

4
इतना पठनीय समाधान, यही कारण है कि लोग स्कैला से प्यार करते हैं I belive :)
प्रार्थनागृह

3
क्यों नहीं .split('\'').get(2)जावा में बस कुछ हद तक? मुझे लगता है कि अगर आपको लगता है कि एक पठनीय समाधान है तो आपको ब्रेन स्कैन करवाना पड़ सकता है - ऐसा लगता है कि कोई मेरे लिए कुछ कोड गोल्फ करने की कोशिश कर रहा है।
ArtOfWarfare


4

जावास्क्रिप्ट में के रूप में:

mydata.match(/'([^']+)'/)[1]

वास्तविक regexp है: /'([^']+)'/

यदि आप गैर लालची संशोधक का उपयोग करते हैं (एक अन्य पोस्ट के अनुसार) यह इस तरह है:

mydata.match(/'(.*?)'/)[1]

यह क्लीनर है।


2

स्काला में,

val ticks = "'([^']*)'".r

ticks findFirstIn mydata match {
    case Some(ticks(inside)) => println(inside)
    case _ => println("nothing")
}

for (ticks(inside) <- ticks findAllIn mydata) println(inside) // multiple matches

val Some(ticks(inside)) = ticks findFirstIn mydata // may throw exception

val ticks = ".*'([^']*)'.*".r    
val ticks(inside) = mydata // safe, shorter, only gets the first set of ticks


1

Apache Commons Lang java.lang API के लिए सहायक उपयोगिताओं का एक मेजबान प्रदान करता है, विशेष रूप से स्ट्रिंग हेरफेर के तरीके। आपके मामले में, प्रारंभ और अंत सबस्ट्रिंग समान हैं, इसलिए बस निम्नलिखित फ़ंक्शन को कॉल करें।

StringUtils.substringBetween(String str, String tag)

स्ट्रिंग जो एक ही स्ट्रिंग के दो उदाहरणों के बीच में निहित है

यदि प्रारंभ और अंत सबस्ट्रिंग अलग-अलग हैं, तो निम्न अधिभार विधि का उपयोग करें।

StringUtils.substringBetween(String str, String open, String close)

स्ट्रिंग है कि दो स्ट्रिंग्स के बीच में निहित है हो जाता है।

यदि आप मेल खाने वाले सबस्ट्रिंग के उदाहरण चाहते हैं, तो उपयोग करें,

StringUtils.substringsBetween(String str, String open, String close)

एक शुरुआत और अंत टैग द्वारा सीमांकित सबस्ट्रिंग के लिए एक स्ट्रिंग खोजता है, जो सभी मिलान सब्सट्रिंग को एक सरणी में लौटाता है

प्रश्न में उदाहरण के लिए मेल खाने वाले विकल्प के सभी उदाहरण प्राप्त करने के लिए

String[] results = StringUtils.substringsBetween(mydata, "'", "'");

0

यदि आप उपयोग करते हैं, तो आप इसे उपयोग कर सकते हैं जबकि लूप सरणी में प्रतिस्थापित सभी मैचों को संग्रहीत करने के लिए उपयोग कर सकते हैं

if (matcher.find()) { System.out.println(matcher.group(1)); }

आप सबस्टेशन से मेल खाते हैं, इसलिए आप इसका उपयोग सभी मैचों को प्रतिस्थापित करने के लिए कर सकते हैं

Matcher m = Pattern.compile("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+").matcher(text);
   // Matcher  mat = pattern.matcher(text);
    ArrayList<String>matchesEmail = new ArrayList<>();
        while (m.find()){
            String s = m.group();
            if(!matchesEmail.contains(s))
                matchesEmail.add(s);
        }

    Log.d(TAG, "emails: "+matchesEmail);

0

अपने pom.xml पर apache.commons निर्भरता जोड़ें

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-io</artifactId>
    <version>1.3.2</version>
</dependency>

और नीचे कोड काम करता है।

StringUtils.substringBetween(String mydata, String "'", String "'")

0

कुछ (1) समूह ने मेरे लिए कैसे काम किया। मैंने url संस्करण को खोजने के लिए समूह (0) का उपयोग किया।

Pattern urlVersionPattern = Pattern.compile("\\/v[0-9][a-z]{0,1}\\/");
Matcher m = urlVersionPattern.matcher(url);
if (m.find()) { 
    return StringUtils.substringBetween(m.group(0), "/", "/");
}
return "v0";
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.