2010-09-10 17 views
6

मैं फ़ाइल से स्ट्रिंग से मेल खाने के लिए स्कैनर के साथ नियमित अभिव्यक्ति का उपयोग करने का प्रयास कर रहा हूं। रेगुलर एक्सप्रेशन से इस लाइन के अलावा फ़ाइल की सामग्री के सभी के साथ काम करता है:मेरा रेगेक्स जावा में एक स्टैक ओवरफ़्लो पैदा कर रहा है; मैं क्या खो रहा हूँ?

DNA="ITTTAITATIATYAAAYIYI[....]ITYTYITTIYAIAIYIT" 
वास्तविक फ़ाइल में

, अंडाकार कई हजार अधिक वर्ण का प्रतिनिधित्व करता है।

जब फ़ाइल को पढ़ने वाला लूप बेस युक्त रेखा पर आता है, तो एक स्टैक ओवरफ़्लो त्रुटि होती है।

while (scanFile.hasNextLine()) { 
    final String currentLine = scanFile.findInLine(".*"); 
    System.out.println("trying to match '" + currentLine + "'"); 
    Scanner internalScanner = new Scanner(currentLine); 
    String matchResult = internalScanner.findInLine(Constants.ANIMAL_INFO_REGEX); 
    assert matchResult != null : "there's no reason not to find a match"; 
    matches.put(internalScanner.match().group(1), internalScanner.match().group(2)); 
    scanFile.nextLine(); 
    } 

और regex::

static final String ANIMAL_INFO_REGEX = "([a-zA-Z]+) *= *\"(([a-zA-Z_.]| |\\.)+)"; 

यहाँ विफलता का पता लगाने है:

java.lang.StackOverflowError 
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3360) 
    at java.util.regex.Pattern$Branch.match(Pattern.java:4131) 
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4185) 
    at java.util.regex.Pattern$Loop.match(Pattern.java:4312) 
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4244) 
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4095) 
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3362) 
    at java.util.regex.Pattern$Branch.match(Pattern.java:4131) 
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4185) 
    at java.util.regex.Pattern$Loop.match(Pattern.java:4312) 
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4244) 
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4095) 
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3362) 
    at java.util.regex.Pattern$Branch.match(Pattern.java:4131) 
    at java.util.regex.Pattern$GroupHead.match(Pattern.java:4185) 
    at java.util.regex.Pattern$Loop.match(Pattern.java:4312) 
    at java.util.regex.Pattern$GroupTail.match(Pattern.java:4244) 
    at java.util.regex.Pattern$BranchConn.match(Pattern.java:4095) 
    ...etc (it's all regex). 

धन्यवाद इतना

यहाँ पाश है!

+0

मैं देख सकता हूँ कि यह आपको एक stackoverflow ... प्राप्त करने के लिए कारण बनता है: पी ~ –

उत्तर

3

अपने रेगेक्स के इस सरलीकृत संस्करण को आजमाएं जो कुछ अनावश्यक | ऑपरेटरों को हटा देता है (जो रेगेक्स इंजन को बहुत सारी शाखाएं करने का कारण बन रहा है) और इसमें लाइन एंकरों की शुरुआत और अंत शामिल है।

static final String ANIMAL_INFO_REGEX = "^([a-zA-Z]+) *= *\"([a-zA-Z_. ]+)\"$"; 
4

यह bug 5050507 जैसा दिखता है। मैं आसाफ से सहमत हूं कि विकल्प को हटाने में मदद करनी चाहिए; बग विशेष रूप से कहता है "जब भी संभव हो वैकल्पिक विकल्प से बचें"। मुझे लगता है कि आप शायद जा सकते हैं और भी आसान:

"^([a-zA-Z]+) *= *\"([^\"]+)" 
+1

+1, लेकिन मैं जोर देना है कि बग ** रिपोर्ट चाहते ** फर्जी है मूल्यांकन में टिप्पणियां * किसी भी * रेगेक्स-निर्देशित (या एनएफए) रेगेक्स इंजन पर लागू होती हैं, न केवल जावा की। (इसमें पर्ल, पायथन, PHP, .NET, जावास्क्रिप्ट, और कई अन्य शामिल हैं।) –

1

से एक का उपयोग के रूप में अन्य लोगों ने कहा, अपने रेगुलर एक्सप्रेशन से बहुत कम है इससे कुशल होना चाहिए। मैं इसे एक कदम आगे ले और अधिकार परिमाणकों का उपयोग करेंगे:

"^([a-zA-Z]++) *+= *+\"([^\"]++)\"$" 

लेकिन जिस तरह से आप स्कैनर का उपयोग कर रहे ज्यादा मतलब नहीं है, या तो। लाइन पढ़ने के लिए findInLine(".*") का उपयोग करने की आवश्यकता नहीं है; यही nextLine() करता है। और आपको अपने रेगेक्स को लागू करने के लिए एक और स्कैनर बनाने की आवश्यकता नहीं है; बस एक Matcher का उपयोग करें।

static final Pattern ANIMAL_INFO_PATTERN = 
    Pattern.compile("^([a-zA-Z]++) *+= *+\"([^\"]++)\"$"); 

...

Matcher lineMatcher = ANIMAL_INFO_PATTERN.matcher(""); 
    while (scanFile.hasNextLine()) { 
    String currentLine = scanFile.nextLine(); 
    if (lineMatcher.reset(currentLine).matches()) { 
     matches.put(lineMatcher.group(1), lineMatcher.group(2)); 
    } 
    } 
संबंधित मुद्दे