जावा में मान निकालने के लिए नियमित अभिव्यक्तियों का उपयोग करना


169

मेरे पास मोटे रूप में कई तार हैं:

[some text] [some number] [some more text]

मैं जावा रेगेक्स कक्षाओं का उपयोग करके पाठ को [कुछ संख्या में] निकालना चाहता हूं।

मैं मोटे तौर पर जानता हूं कि मैं किस नियमित अभिव्यक्ति का उपयोग करना चाहता हूं (हालांकि सभी सुझावों का स्वागत है)। क्या मैं वास्तव में रुचि रखता हूं जावा कॉल रेगीक्स स्ट्रिंग ले रहा हूं और [कुछ संख्या] के मूल्य का उत्पादन करने के लिए स्रोत डेटा पर इसका उपयोग करता हूं।

संपादित करें: मुझे यह जोड़ना चाहिए कि मुझे केवल एक [कुछ संख्या] (मूल रूप से, पहला उदाहरण) में दिलचस्पी है। स्रोत के तार कम हैं और मैं [कुछ संख्या] की कई घटनाओं की तलाश में नहीं जा रहा हूँ।


11
... और अब मैं अनुसंधान के लिए रवाना हो गया हूं। आइए देखें कि क्या मैं अपने बारे में जानने से पहले एसओ को जवाब दे सकता हूं। :-P
क्रेग वॉकर

यह सॉफ्टवेयर इंजीनियरिंग के लिए बैंकिंग / निवेश / ट्रेडिंग कंपनी में एक साक्षात्कार प्रश्न था? : पी
14

@ हेन्थ नोप, करीब भी नहीं! यह एक छोटे से बिज़ वेबसाइट पर उत्पादन कोड के लिए था ... कई चंद्रमा पहले।
क्रेग वॉकर

1
बहुत अच्छी तरह से मैं एक जेपी मॉर्गन चेस सॉफ्टवेयर इंजीनियरिंग कोडिंग परीक्षा पर लगभग एक ही सटीक सवाल पूछा गया था कुछ दिन पहले: P
ennth

जवाबों:


316

पूर्ण उदाहरण:

private static final Pattern p = Pattern.compile("^([a-zA-Z]+)([0-9]+)(.*)");
public static void main(String[] args) {
    // create matcher for pattern p and given string
    Matcher m = p.matcher("Testing123Testing");

    // if an occurrence if a pattern was found in a given string...
    if (m.find()) {
        // ...then you can use group() methods.
        System.out.println(m.group(0)); // whole matched expression
        System.out.println(m.group(1)); // first expression from round brackets (Testing)
        System.out.println(m.group(2)); // second one (123)
        System.out.println(m.group(3)); // third one (Testing)
    }
}

जब से आप पहले नंबर की तलाश कर रहे हैं, आप ऐसे regexp का उपयोग कर सकते हैं:

^\D+(\d+).*

और m.group(1)आपको पहला नंबर लौटाएगा। ध्यान दें कि हस्ताक्षरित संख्याओं में ऋण चिह्न हो सकता है:

^\D+(-?\d+).*

62
Patter ऑब्जेक्ट का पुन: उपयोग करने के लिए मत भूलना। संरक्षक के संकलन में बड़ी मात्रा में समय लगता है।
रास्टीस्लाव कोमरा

14
माना। आमतौर पर मैं पैटर्न को एक निजी स्थिर अंतिम पैटर्न पैटर्न के रूप में परिभाषित करता हूं = पैटर्न.कॉमपाइल ("..."); लेकिन वह सिर्फ मैं हूं।
एलन लालोंडे

6
हम बस पैटर्न p = Pattern.compile ("\\ d +") का उपयोग कर सकते हैं;
जावा मैन

15
स्पष्टीकरण के बिना यह एक खराब जवाब है।
मार्टिन स्पामर

आप मिलानकर्ता का पुन: उपयोग भी कर सकते हैं। प्रत्येक उपयोग के बीच मिलानकर्ता रीसेट () विधि को कॉल करें। यदि आप कई समवर्ती धागे में माचिस साझा कर रहे हैं, तो आपको ऑपरेशन को सिंक्रनाइज़ करना चाहिए।
मार्केज़

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

public class Regex1 {
    public static void main(String[]args) {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("hello1234goodboy789very2345");
        while(m.find()) {
            System.out.println(m.group());
        }
    }
}

आउटपुट:

1234
789
2345

सवाल विशेष रूप से संख्याओं की केवल पहली घटना के लिए पूछता है।
NoBrainer

34

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

"(\\d+)"

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

यदि आप इसे रिक्त स्थान से ऑफसेट होने की उम्मीद करते हैं, तो यह निर्दिष्ट करने के लिए और भी अधिक विशिष्ट बना देगा

"\\s+(\\d+)\\s+"

बेहतर हो सकता है।

यदि आपको सभी तीन भागों की आवश्यकता है, तो यह होगा:

"(\\D+)(\\d+)(.*)"

संपादित करें भाव Allain और जैक द्वारा दिए गए सुझाव है कि आप पर कब्जा करने के लिए गैर-अंक में से कुछ सबसेट निर्दिष्ट अंक । यदि आप रेगेक्स इंजन को बता रहे हैं जिसे आप खोज रहे हैं \dतो यह अंकों से पहले सब कुछ अनदेखा कर देगा। जम्मू या एक की अभिव्यक्ति हैं फिट बैठता है अपने प्रतिमान, फिर पूरे मैच के बराबर होती है इनपुट स्ट्रिंग । और इसे निर्दिष्ट करने का कोई कारण नहीं है। यह पूरी तरह से नजरअंदाज नहीं किया गया है, तो यह शायद एक साफ मैच धीमा कर देती है।


आप नमूना परीक्षण चलाकर और उसके बनाम ए / जे समाधान के प्रदर्शन की जांच करके एक्समैन की परिकल्पना का परीक्षण कर सकते हैं।
अंजन

आपको स्ट्रिंग की शुरुआत और अंत निर्दिष्ट करने की आवश्यकता नहीं है। अन्यथा 124xxx123xxx जैसी चीजों का मिलान किया जाएगा, भले ही वह उसके वाक्य-विन्यास में फिट न हो? या ^ और $ निहित हैं?
एलन लालोंडे

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

11

पैटर्न के अलावा , जावा स्ट्रिंग क्लास में कई तरीके भी होते हैं जो नियमित अभिव्यक्ति के साथ काम कर सकते हैं, आपके मामले में कोड होगा:

"ab123abc".replaceFirst("\\D*(\\d*).*", "$1")

\\Dएक गैर-अंक वर्ण कहां है।


10

जावा 1.4 में और ऊपर:

String input = "...";
Matcher matcher = Pattern.compile("[^0-9]+([0-9]+)[^0-9]+").matcher(input);
if (matcher.find()) {
    String someNumberStr = matcher.group(1);
    // if you need this to be an int:
    int someNumberInt = Integer.parseInt(someNumberStr);
}

8

यह फ़ंक्शन स्ट्रिंग से सभी मिलान अनुक्रमों को इकट्ठा करता है। इस उदाहरण में यह स्ट्रिंग से सभी ईमेल पते लेता है।

static final String EMAIL_PATTERN = "[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
        + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})";

public List<String> getAllEmails(String message) {      
    List<String> result = null;
    Matcher matcher = Pattern.compile(EMAIL_PATTERN).matcher(message);

    if (matcher.find()) {
        result = new ArrayList<String>();
        result.add(matcher.group());

        while (matcher.find()) {
            result.add(matcher.group());
        }
    }

    return result;
}

इसके लिए message = "adf@gmail.com, <another@osiem.osiem>>>> lalala@aaa.pl"3 तत्वों की सूची बनाएंगे।


3

ऐसा कुछ करने की कोशिश करें:

Pattern p = Pattern.compile("^.+(\\d+).+");
Matcher m = p.matcher("Testing123Testing");

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

3
-1। क्योंकि .+लालच पात्रों का उपभोग करता है, \d+केवल से पकड़ता "3"है "123"। इसके अलावा, स्ट्रिंग शाब्दिक के अंदर, आपको बैकस्लैश से बचने की जरूरत है (आपका उदाहरण संकलन नहीं करेगा)।
बार्ट कीर्स

3

सरल उपाय

// Regexplanation:
// ^       beginning of line
// \\D+    1+ non-digit characters
// (\\d+)  1+ digit characters in a capture group
// .*      0+ any character
String regexStr = "^\\D+(\\d+).*";

// Compile the regex String into a Pattern
Pattern p = Pattern.compile(regexStr);

// Create a matcher with the input String
Matcher m = p.matcher(inputStr);

// If we find a match
if (m.find()) {
    // Get the String from the first capture group
    String someDigits = m.group(1);
    // ...do something with someDigits
}

एक उपयोगिता वर्ग में समाधान

public class MyUtil {
    private static Pattern pattern = Pattern.compile("^\\D+(\\d+).*");
    private static Matcher matcher = pattern.matcher("");

    // Assumptions: inputStr is a non-null String
    public static String extractFirstNumber(String inputStr){
        // Reset the matcher with a new input String
        matcher.reset(inputStr);

        // Check if there's a match
        if(matcher.find()){
            // Return the number (in the first capture group)
            return matcher.group(1);
        }else{
            // Return some default value, if there is no match
            return null;
        }
    }
}

...

// Use the util function and print out the result
String firstNum = MyUtil.extractFirstNumber("Testing4234Things");
System.out.println(firstNum);

1

देखो आप इसे StringTokenizer का उपयोग करके कर सकते हैं

String str = "as:"+123+"as:"+234+"as:"+345;
StringTokenizer st = new StringTokenizer(str,"as:");

while(st.hasMoreTokens())
{
  String k = st.nextToken();    // you will get first numeric data i.e 123
  int kk = Integer.parseInt(k);
  System.out.println("k string token in integer        " + kk);

  String k1 = st.nextToken();   //  you will get second numeric data i.e 234
  int kk1 = Integer.parseInt(k1);
  System.out.println("new string k1 token in integer   :" + kk1);

  String k2 = st.nextToken();   //  you will get third numeric data i.e 345
  int kk2 = Integer.parseInt(k2);
  System.out.println("k2 string token is in integer   : " + kk2);
}

चूंकि हम इन संख्यात्मक डेटा को तीन अलग-अलग चर में ले रहे हैं इसलिए हम इस डेटा को कोड में (आगे उपयोग के लिए) कहीं भी उपयोग कर सकते हैं


0

कैसे के बारे में [^\\d]*([0-9]+[\\s]*[.,]{0,1}[\\s]*[0-9]*).*मुझे लगता है कि यह आंशिक भाग के साथ संख्याओं का ख्याल रखेगा। मैंने सफेद रिक्त स्थान शामिल किए ,और संभव विभाजक के रूप में शामिल किया। मैं एक स्ट्रिंग से संख्याओं को प्राप्त करने की कोशिश कर रहा हूं, जिसमें फ़्लोट्स शामिल हैं और इस बात को ध्यान में रखते हुए कि उपयोगकर्ता एक गलती कर सकता है और संख्या लिखते समय सफेद रिक्त स्थान शामिल कर सकता है।


0

कभी-कभी आप java.lang.String में उपलब्ध सरल .split ("REGEXP") विधि का उपयोग कर सकते हैं। उदाहरण के लिए:

String input = "first,second,third";

//To retrieve 'first' 
input.split(",")[0] 
//second
input.split(",")[1]
//third
input.split(",")[2]

0
Pattern p = Pattern.compile("(\\D+)(\\d+)(.*)");
Matcher m = p.matcher("this is your number:1234 thank you");
if (m.find()) {
    String someNumberStr = m.group(2);
    int someNumberInt = Integer.parseInt(someNumberStr);
}

1
कृपया अधिक जानकारी के साथ संपादित करें। कोड-ओनली एंड "ट्राय दिस" जवाबों को हतोत्साहित किया जाता है, क्योंकि उनमें कोई खोज योग्य सामग्री नहीं होती है, और यह नहीं समझाते कि किसी को "कोशिश" क्यों करनी चाहिए। हम ज्ञान के लिए संसाधन होने के लिए यहाँ एक प्रयास करते हैं।
ब्रायन टॉम्पसेट -

1
डाउनवोट केवल सही उत्तरों को दोहराने के लिए, जो बिना किसी अतिरिक्त मूल्य को जोड़ने के लिए बहुत समय पहले दिए गए हैं
फॉरएज

-1

अगर आप फ़ाइल से पढ़ रहे हैं तो यह आपकी मदद कर सकता है

              try{
             InputStream inputStream = (InputStream) mnpMainBean.getUploadedBulk().getInputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
             String line;
             //Ref:03
             while ((line = br.readLine()) != null) {
                if (line.matches("[A-Z],\\d,(\\d*,){2}(\\s*\\d*\\|\\d*:)+")) {
                     String[] splitRecord = line.split(",");
                     //do something
                 }
                 else{
                     br.close();
                     //error
                     return;
                 }
             }
                br.close();

             }
         }
         catch (IOException  ioExpception){
             logger.logDebug("Exception " + ioExpception.getStackTrace());
         }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.