2010-09-10 34 views
6

Tôi đang cố gắng sử dụng cụm từ thông dụng với Trình quét để khớp với chuỗi từ tệp. Regex hoạt động với tất cả nội dung của tệp ngoại trừ dòng này:Regex của tôi đang gây ra tràn ngăn xếp trong Java; tôi đang thiếu gì?

DNA="ITTTAITATIATYAAAYIYI[....]ITYTYITTIYAIAIYIT" 

trong tệp thực, dấu ba chấm thể hiện vài nghìn ký tự.

Khi vòng lặp đọc tệp đến trên dòng chứa các đế, xảy ra lỗi tràn ngăn xếp.

Đây là vòng lặp:

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(); 
    } 

và regex:

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

Đây là dấu vết thất bại:

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). 

Cảm ơn rất nhiều!

+0

tôi có thể thấy rằng nó làm cho bạn để có được một stackoverflow ...: P ~ –

Trả lời

3

Hãy thử phiên bản đơn giản này của regex để loại bỏ một số toán tử không cần thiết | (có thể đã khiến động cơ regex thực hiện nhiều nhánh) và bao gồm đầu và cuối của đường kẻ.

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

Điều này có vẻ như bug 5050507. Tôi đồng ý với Asaph rằng việc loại bỏ sự thay đổi sẽ giúp; lỗi cụ thể nói "Tránh thay đổi bất cứ khi nào có thể". Tôi nghĩ rằng bạn có thể đi có lẽ thậm chí đơn giản hơn:

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

+1, nhưng tôi muốn nhấn mạnh rằng lỗi ** Báo cáo ** là không có thật. Các nhận xét trong Đánh giá áp dụng cho * bất kỳ công cụ regex nào có chỉ số regex (hoặc NFA), không chỉ của Java. (Điều đó bao gồm Perl, Python, PHP, .NET, JavaScript và nhiều thứ khác.) –

1

Như những người khác đã nói, regex của bạn là ít hơn nhiều hiệu quả hơn nó nên được. Tôi sẽ tiến thêm một bước nữa và sử dụng các định lượng sở hữu:

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

Nhưng cách bạn đang sử dụng Trình quét cũng không có ý nghĩa gì nhiều. Không cần sử dụng findInLine(".*") để đọc dòng; đó là những gì nextLine() làm. Và bạn không cần phải tạo một Máy quét khác để áp dụng regex của bạn; chỉ cần sử dụng một 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)); 
    } 
    } 
Các vấn đề liên quan