रेगुलर एक्सप्रेशन का उपयोग करके एक बड़ी स्ट्रिंग के विकल्प खोजने के लिए जावा का उपयोग करना


140

अगर मेरे पास इस तरह से एक स्ट्रिंग है:

FOO[BAR]

मुझे स्ट्रिंग से "BAR" स्ट्रिंग प्राप्त करने के लिए एक सामान्य तरीके की आवश्यकता है ताकि कोई फर्क नहीं पड़ता कि स्ट्रिंग वर्ग कोष्ठक के बीच है जो स्ट्रिंग प्राप्त करने में सक्षम होगी।

जैसे

FOO[DOG] = DOG
FOO[CAT] = CAT

जवाबों:


253

आप विशेष रूप से *, गैर-लालची मात्रा का उपयोग करने में सक्षम होना चाहिए। आप शायद निम्नलिखित चाहते हैं:

Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");

यह आपको एक पैटर्न देगा जो आपके स्ट्रिंग से मेल खाएगा और पहले समूह में वर्ग कोष्ठक के भीतर पाठ डाल देगा। अधिक जानकारी के लिए पैटर्न एपीआई प्रलेखन पर एक नजर है ।

स्ट्रिंग को निकालने के लिए, आप निम्नलिखित जैसे कुछ का उपयोग कर सकते हैं:

Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
    String s = m.group(1);
    // s now contains "BAR"
}

16
यह ध्यान देने योग्य है कि यदि चौकोर कोष्ठकों के बीच एक नई रेखा है, तो यह विफल हो जाएगा और इससे बचने के लिए आपको पैट्रोल.डोटल ध्वज का उपयोग करना चाहिए।
क्लेटस

उपरोक्त पैटर्न का उपयोग करते हुए, आप तब कैसे उपयोग करेंगे कि स्ट्रिंग स्ट्रिंग को निकालने के लिए BAR? मैं पैटर्न एपीआई और मिलान एपीआई देख रहा हूं, लेकिन मुझे अभी भी यकीन नहीं है कि स्ट्रिंग को कैसे प्राप्त किया जाए।
डिजीवर्नी

@ क्लेटस: अच्छा कॉल! @digiarnie: मैंने उत्तर में एक संशोधन जोड़ा है जिसमें मैच पाने के लिए कुछ स्ट्रॉ-मैन कोड शामिल हैं।
ब्रायन काइल

30

गैर-रेगेक्स तरीका:

String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));

वैकल्पिक रूप से, थोड़ा बेहतर प्रदर्शन / स्मृति उपयोग के लिए (धन्यवाद होसम):

String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));

1
मैं lastIndexOf(']')इसके बजाय का उपयोग करेगा , जो नेस्टेड कोष्ठक संभालना होगा। इसके अतिरिक्त, मेरा मानना ​​है कि का उपयोग करने की indexOf(char)तुलना में तेज होगा indexOf(String)
होसम ऐली

आपका स्वागत है। प्रदर्शन के बारे में आपका नोट भी बहुत प्रासंगिक है, क्योंकि lastIndexOfसमापन ब्रैकेट को खोजने के लिए निश्चित रूप से तेज़ होगा।
होसम ऐली

3
क्या तेजी से है, इंडेक्सऑफ सबस्ट्रिंग आदि आदि या रीजेक्स?
टॉस्कन

2
नीचे "निकाले गए" के लिए अमित का मूल्य देखें: input.indexOf ('[') + 1
gcbound

28

यह एक कार्य उदाहरण है:

RegexpExample.java

package org.regexp.replace;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexpExample
{
    public static void main(String[] args)
    {
        String string = "var1[value1], var2[value2], var3[value3]";
        Pattern pattern = Pattern.compile("(\\[)(.*?)(\\])");
        Matcher matcher = pattern.matcher(string);

        List<String> listMatches = new ArrayList<String>();

        while(matcher.find())
        {
            listMatches.add(matcher.group(2));
        }

        for(String s : listMatches)
        {
            System.out.println(s);
        }
    }
}

यह प्रदर्शित करता है :

value1
value2
value3

6
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public static String get_match(String s, String p) {
    // returns first match of p in s for first group in regular expression 
    Matcher m = Pattern.compile(p).matcher(s);
    return m.find() ? m.group(1) : "";
}

get_match("FOO[BAR]", "\\[(.*?)\\]")  // returns "BAR"

public static List<String> get_matches(String s, String p) {
    // returns all matches of p in s for first group in regular expression 
    List<String> matches = new ArrayList<String>();
    Matcher m = Pattern.compile(p).matcher(s);
    while(m.find()) {
        matches.add(m.group(1));
    }
    return matches;
}

get_matches("FOO[BAR] FOO[CAT]", "\\[(.*?)\\]")) // returns [BAR, CAT]

5

यदि आपको बस जो कुछ भी प्राप्त करने की आवश्यकता है [], आप \[([^\]]*)\]इस तरह का उपयोग कर सकते हैं :

Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
    result = m.group();
}

यदि आपको फॉर्म की आवश्यकता है identifier + [ + content + ]तो आप केवल तभी सामग्री निकालने को सीमित कर सकते हैं जब पहचानकर्ता एक अल्फ़ान्यूमेरिकल है:

[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]

यह उदाहरण के लिए Foo [Bar], या जैसी चीजों को मान्य करेगा myDevice_123["input"]

मुख्य मुद्दा

मुख्य समस्या यह है कि जब आप कुछ इस तरह की सामग्री को निकालना चाहते हैं:

FOO[BAR[CAT[123]]+DOG[FOO]]

Regex काम नहीं करेगा और वापस आ जाएगी BAR[CAT[123और FOO
यदि हम Regex को बदल \[(.*)\]देते हैं तो हम ठीक हैं लेकिन फिर, यदि आप अधिक जटिल चीजों से सामग्री निकालने का प्रयास कर रहे हैं जैसे:

FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]

रेगेक्स में से कोई भी काम नहीं करेगा।

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

एक सरल उपाय

यदि आपकी समस्याएं जटिल हो रही हैं और []मनमानी की सामग्री है , तो आप इसके बजाय जोड़े को संतुलित कर सकते हैं []और एक रेगेक्स की तुलना में सादे पुराने कोड रिटे का उपयोग करके स्ट्रिंग को निकाल सकते हैं:

int i;
int brackets = 0;
string c;
result = "";
for (i = input.indexOf("["); i < str.length; i++) {
    c = str.substring(i, i + 1);
    if (c == '[') {
        brackets++;
    } else if (c == ']') {
        brackets--;
        if (brackets <= 0) 
            break;
    }
    result = result + c;
}   

यह वास्तविक कोड की तुलना में अधिक छद्म कोड है, मैं जावा कोडर नहीं हूं इसलिए मुझे पता नहीं है कि क्या सिंटैक्स सही है, लेकिन इसे सुधारना काफी आसान होना चाहिए।
क्या गिनती है कि यह कोड काम करना चाहिए और आपको सामग्री को निकालने की अनुमति दे सकता है [], हालांकि यह जटिल है।


2

मुझे लगता है कि आपकी नियमित अभिव्यक्ति इस तरह दिखाई देगी:

/FOO\[(.+)\]/

यह मानते हुए कि FOO स्थिर रहने वाला है।

तो, इसे जावा में रखने के लिए:

Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);

FOO [BAR] FOO [BAZ] -> आपके रेगेक्स के साथ लौटेगा: "BAR] FOO [BAZ"
मोहम्मद जाफर मशहदी

1
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));

यह पहले '[' और अंतिम '] के बीच का मान लौटाएगा

फु [बार] => बार

फू [बार [परीक्षण]] => बार [परीक्षण]

नोट: यदि इनपुट स्ट्रिंग ठीक से नहीं बनी है, तो आपको त्रुटि जाँच को जोड़ना चाहिए।


0

यह मानते हुए कि किसी अन्य समापन वर्ग कोष्ठक के भीतर अनुमति नहीं है, / FOO \ [([^ \]] *) \] /


0

मैं परिभाषित करता हूं कि मुझे अधिकतम संख्या में गैर-] अक्षर चाहिए [और ]। इन्हें बैकस्लैश (और जावा में, फिर से भाग जाने की आवश्यकता है) के साथ भाग जाने की आवश्यकता है, और गैर-] की परिभाषा एक चरित्र वर्ग है, इस प्रकार अंदर [और ](यानी [^\\]])। परिणाम:

FOO\\[([^\\]]+)\\]

0

अगर आप कुछ स्ट्रिंग को पार्स करना चाहते हैं, जो mYearInDB.toString () = [2013] से आती है, तो इसके काम को यह 2013 देगा

Matcher n = MY_PATTERN.matcher("FOO[BAR]"+mYearInDB.toString());
while (n.find()) {
 extracredYear  = n.group(1);
 // s now contains "BAR"
    }
    System.out.println("Extrated output is : "+extracredYear);

0

यह regexp मेरे लिए काम करता है:

form\[([^']*?)\]

उदाहरण:

form[company_details][0][name]
form[company_details][0][common_names][1][title]

उत्पादन:

Match 1
1.  company_details
Match 2
1.  company_details

Http://rubular.com/ पर परीक्षण किया गया


0
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");

यह वर्गाकार कोष्ठकों के भीतर केवल एक स्ट्रिंग ले जा रहा है।

यह चौकोर कोष्ठक से बाहर सभी स्ट्रिंग को हटाता है।

आप इस जावा सैंपल कोड का ऑनलाइन परीक्षण कर सकते हैं: http://tpcg.io/wZoFu0

आप इस रेगेक्स का परीक्षण यहां से कर सकते हैं: https://regex101.com/r/oUAzsS/1

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.