2013-06-15 8 views
9

Próbuję przechwycić zawartość z wyrażeń regularnych wielowierszowych. To nie pasuje.Przechwytywanie regex z wieloma wierszami w Scali

val text = """<p>line1 
    line2</p>""" 

val regex = """(?m)<p>(.*?)</p>""".r 

var result = regex.findFirstIn(text).getOrElse("") 

Zwroty są puste.

Umieszczam flagę m - dla multilinii, ale w tym przypadku nie pomaga.

Po usunięciu podziałki linii działa wyrażenie regularne.

Znalazłem również this, ale nie mogłem go uruchomić.

Jak dopasować zawartość między elementami <p>? Chcę wszystko między, również przerwy w linii.

Z góry dziękuję!

+1

Głównym zaleceniem, http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags wskazuje to może być lepiej nie używać wyrażeń regularnych do parsowania HTML w większości przypadków. – Martijn

Odpowiedz

20

Jeśli chcesz aktywować tryb dotall w Scala, należy użyć (?s) zamiast (?m)

(?s) oznacza kropka można dopasować newlines

(?m) oznacza ^ i $ oznaczają początek i koniec linii

+0

Yup ... '(? M)' zmieni zachowanie '^' i '$'. Mylące nazwy;) – fge

+0

@fge mylące, ale m = multi, s = pojedyncza linia. –

+1

Coś, co zajęło mi trochę czasu, aby zdać sobie sprawę, i było konieczne do mojego wniosku: m i s nie wykluczają się wzajemnie. Możesz mieć (? Ms) i będzie działać tak, jakbyś oczekiwał. – Sushisource

5

Jeśli nie jest to w tym momencie oczywiste, "Jak mogę dopasować zawartość":

scala> val regex = """(?s)<p>(.*?)</p>""".r 

scala> (regex findFirstMatchIn text).get group 1 
res52: String = 
line1 
    line2 

Więcej idiomatically,

scala> text match { case regex(content) => content } 
res0: String = 
line1 
    line2 

scala> val embedded = s"stuff${text}morestuff" 
embedded: String = 
stuff<p>line1 
    line2</p>morestuff 

scala> val regex = """(?s)<p>(.*?)</p>""".r.unanchored 
regex: scala.util.matching.UnanchoredRegex = (?s)<p>(.*?)</p> 

scala> embedded match { case regex(content) => content } 
res1: String = 
line1 
    line2 
Powiązane problemy