2009-07-06 26 views
20

Tôi đang học Scala, vì vậy, điều này có thể khá tuyệt vời.Scala Regex bật tùy chọn Đa phương tiện

Tôi muốn có biểu thức chính quy nhiều dòng.

Trong Ruby nó sẽ là:

MY_REGEX = /com:Node/m 

Scala của tôi trông giống như:

val ScriptNode = new Regex("""<com:Node>""") 

Dưới đây là chức năng phù hợp với tôi:

def matchNode(value : String) : Boolean = value match 
{ 
    case ScriptNode() => System.out.println("found" + value); true 
    case _ => System.out.println("not found: " + value) ; false 
} 

Và tôi gọi nó như vậy:

matchNode("<root>\n<com:Node>\n</root>") // doesn't work 
matchNode("<com:Node>") // works 

Tôi đã thử:

val ScriptNode = new Regex("""<com:Node>?m""") 

Và tôi thực sự muốn tránh phải sử dụng java.util.regex.Pattern. Bất kỳ mẹo nào được đánh giá cao.

+0

cổ vũ để định dạng! không làm việc cho tôi –

+1

Bạn phải để trống một dòng ở trên và bên dưới mỗi khối mã. –

Trả lời

36

Đây là vấn đề rất phổ biến khi lần đầu tiên sử dụng Scala Regex.

Khi bạn sử dụng đối sánh mẫu trong Scala, nó cố khớp với toàn bộ chuỗi, như thể bạn đang sử dụng "^" và "$" (và không kích hoạt phân tích nhiều dòng, khớp với \ n đến^và $).

Cách để làm những gì bạn muốn sẽ là một trong những cách sau:

def matchNode(value : String) : Boolean = 
    (ScriptNode findFirstIn value) match {  
    case Some(v) => println("found" + v); true  
    case None => println("not found: " + value) ; false 
    } 

Trong đó sẽ tìm thấy trường hợp đầu tiên của ScriptNode bên trong giá trị, và trở rằng dụ như v (nếu bạn muốn toàn bộ chuỗi, chỉ cần in giá trị). Hoặc người nào khác:

val ScriptNode = new Regex("""(?s).*<com:Node>.*""") 
def matchNode(value : String) : Boolean = 
    value match {  
    case ScriptNode() => println("found" + value); true  
    case _ => println("not found: " + value) ; false 
    } 

Mà sẽ in tất cả giá trị. Trong ví dụ này, (? S) kích hoạt kết hợp dấu chấm (tức là, khớp "." Với các dòng mới), và. * Trước và sau mẫu tìm kiếm, đảm bảo nó sẽ khớp với bất kỳ chuỗi nào. Nếu bạn muốn "v" như trong ví dụ đầu tiên, bạn có thể làm điều này:

val ScriptNode = new Regex("""(?s).*(<com:Node>).*""") 
def matchNode(value : String) : Boolean = 
    value match {  
    case ScriptNode(v) => println("found" + v); true  
    case _ => println("not found: " + value) ; false 
    } 
+1

Nội dung đáng yêu. Chúc mừng! –

+21

Có thể không rõ ràng đối với người đọc lướt như tôi, nhưng sự bao gồm '(? S)' là chìa khóa ở đây liên quan đến kết hợp với chuỗi nhiều dòng. Xem http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html#DOTALL – Synesso

+4

@Synesso liên kết của bạn đã bị hỏng ngay bây giờ. đây là tương đương với java 7 http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#DOTALL – harschware

5

Chỉ cần một phụ lục nhanh chóng và dơ bẩn: phương pháp .r trên RichString chuyển đổi tất cả các chuỗi để scala.util.matching.Regex, vì vậy bạn có thể làm một cái gì đó như thế này:

"""(?s)a.*b""".r replaceAllIn ("a\nb\nc\n", "A\nB") 

và đó sẽ trở lại

A 
B 
c 

tôi sử dụng tất cả thời gian cho nhanh chóng và dơ bẩn regex-scripting trong scala con Duy Nhất.

Hoặc trong trường hợp này:

def matchNode(value : String) : Boolean = { 

    """(?s).*(<com:Node>).*""".r.findAllIn(text) match { 

     case ScriptNode(v) => System.out.println("found" + v); true  

     case _ => System.out.println("not found: " + value) ; false 
    } 
} 

Chỉ cần cố gắng của tôi để giảm việc sử dụng các từ new trong mã trên toàn thế giới.;)

3

Chỉ cần một bổ sung nhỏ, sử dụng cố gắng sử dụng (?m) (Multiline) cờ (mặc dù nó có thể không phù hợp ở đây) nhưng đây là đúng cách để sử dụng nó:

ví dụ thay vì

val ScriptNode = new Regex("""<com:Node>?m""") 

sử dụng

val ScriptNode = new Regex("""(?m)<com:Node>""") 

Nhưng một lần nữa (? s) cờ là phù hợp hơn trong câu hỏi này (thêm câu trả lời này chỉ vì tiêu đề là "Scala Regex kích hoạt tùy chọn Multiline")

Các vấn đề liên quan