2013-11-22 26 views
5

Tôi chỉ học cách sử dụng regex của:Regex thực hành tốt nhất

Tôi đọc trong một tập tin văn bản được chia thành các phần của hai loại khác nhau, xác định địa giới <:==]:><:==}:>. Tôi cần phải biết cho từng bộ phận cho dù đó là một ] hay }, vì vậy tôi không thể chỉ làm

pattern.compile("<:==]:>|<:==}:>"); pattern.split(text) 

Việc làm này:

pattern.compile("<:=="); pattern.split(text) 

công trình, và sau đó tôi chỉ có thể nhìn vào char đầu tiên trong mỗi chuỗi con, nhưng điều này có vẻ cẩu thả với tôi, và tôi nghĩ tôi chỉ dùng nó vì tôi không nắm bắt được thứ gì đó tôi cần nắm bắt về regex:

Thực hành tốt nhất ở đây là gì? Ngoài ra, có cách nào để phân chia một chuỗi lên trong khi rời khỏi dấu phân tách trong các chuỗi kết quả - sao cho mỗi chuỗi bắt đầu bằng dấu phân tách?

EDIT: tập tin được đặt ra như thế này:

Old McDonald had a farm 
<:==}:> 
EIEIO. And on that farm he had a cow 
<:==]:> 
And on that farm he.... 
+0

Giải pháp ban đầu của tôi (không bao gồm dấu phân cách trong nhóm) sẽ cần phải suy nghĩ lại. Bạn có thể cung cấp một tệp mẫu nhỏ không? Tôi không hoàn toàn chắc chắn tôi hiểu chính xác các phần được phân cách như thế nào. Chúng có được bao quanh bởi các cặp phân cách hay một phần bắt đầu sau một dấu phân tách và kết thúc bằng dấu phân cách tiếp theo? –

+0

@TimPietzcker Vâng tôi đã có cùng một nhận thức. Xem chỉnh sửa của tôi để biết ví dụ về cách đặt tệp. Chúng không phải là cặp các dấu phân tách, phần cuối của mỗi dấu hiệu được báo hiệu bởi sự bắt đầu của bước tiếp theo. Ngoài ra, tôi nên lưu ý rằng <:?:> biểu thị một số loại thẻ khác – drewmoore

+0

Vì vậy, chính xác những gì bạn muốn làm đầu ra? Phần văn bản cùng với một ']' hoặc '}'? Nếu vậy thì bạn muốn gì cho phần đầu tiên/cuối cùng không được phân tách? Bạn có cần phần văn bản hoặc là đủ để chỉ có các dấu phân cách không? – OGHaza

Trả lời

6

Nó có thể là một ý tưởng tốt hơn không sử dụng split() cho việc này. Thay vào đó, bạn có thể thực hiện một kết quả phù hợp:

List<String> delimList = new ArrayList<String>(); 
List<String> sectionList = new ArrayList<String>(); 
Pattern regex = Pattern.compile(
    "(<:==[\\]}]:>)  # Match a delimiter, capture it in group 1.\n" + 
    "(     # Match and capture in group 2:\n" + 
    " (?:    # the following group which matches...\n" + 
    " (?!<:==[\\]}]:>) # (unless we're at the start of another delimiter)\n" + 
    " .    # any character\n" + 
    ")*    # any number of times.\n" + 
    ")     # End of group 2", 
    Pattern.COMMENTS | Pattern.DOTALL); 
Matcher regexMatcher = regex.matcher(subjectString); 
while (regexMatcher.find()) { 
    delimList.add(regexMatcher.group(1)); 
    sectionList.add(regexMatcher.group(2)); 
} 
+1

Có vẻ như bạn đã hoàn toàn làm điều này. Tôi nghĩ câu trả lời cho tất cả các câu hỏi của bạn là Có. Để biết chi tiết, hãy xem [hướng dẫn biểu thức chính quy này của Jan Goyvaerts] (http://www.regular-expressions.info/tutorial.html), đặc biệt là các phần về [chụp nhóm] (http: //www.regular-expressions .info/brackets.html) và [assartions lookaround] (http://www.regular-expressions.info/lookaround.html). Đối với câu hỏi cuối cùng của bạn, bạn có thể cụ thể hơn không? Có lẽ dưới dạng một câu hỏi khác vì nhận xét không thực sự phù hợp với điều này? –

+0

Tôi thích ví dụ này với các ý kiến, nhưng lưu ý rằng một regex tĩnh thường được biên dịch tĩnh (một lần) và tái sử dụng nhiều lần. Xem thêm: http://stackoverflow.com/questions/4935216/shouldnt-static-patterns-always-be-static cũng xem http://stackoverflow.com/questions/1360113/is-java-regex-thread-safe –