2016-07-08 2 views
1

구성 파일에서 값을 추출하기 위해 하나의 라이너 (오히려 길지만)가 있습니다. 정규 표현식을 두 번 적용하지 않아도 행복하지 않습니다 (한 번은 줄을 일치시키고 그룹을 다시 얻습니다). 이 방법을 피할 수있는 방법에 대한 제안이있는 사람이 있습니까?스칼라 정규 표현식을 사용하여 파일에서 하나의 라이너로 값을 추출합니다.

예 데이터 TEMP.TXT :

scalaVersion=2.11.5 
scalaXMLVersion=1.0.3 
jUnitVersion=4.8.2 
log4JVersion=1.2.17 

"일"라이너

val cfg: File = new File("temp.txt") 
val regexp = """jUnitVersion=(.*)""" 
val version = Source.fromFile(cfg) 
        .getLines 
        .find(_.matches(regexp)) 
        .map(regexp.r.findFirstMatchIn(_).get.group(1)) 
        .getOrElse("NOTFOUND") 
println(version) 

출력

4.8.2 

답변

1
val lines = Seq("scalaVersion=2.11.5", 
    "scalaXMLVersion=1.0.3", 
    "jUnitVersion=4.8.2", 
    "log4JVersion=1.2.17") 
val regexp = new scala.util.matching.Regex("""jUnitVersion=(.*)""") 
val version = lines. 
    flatMap(regexp.findFirstMatchIn(_)). 
    headOption. 
    fold("NOTFOUND")(_.group(1)) 

행의 경우 Source.fromFile (cfg) .getLines로 대체 할 수 있습니다.

일치하는 모든 정규식 패턴을 수집하는 파일을 읽습니다. 첫 번째 일치를 취하여 버전 번호 구성 요소를 추출합니다. 일치하는 줄이 없으면 접기의 "NOTFOUND"브랜치가 사용됩니다.

필터링 대신 일치 항목을 유지 한 다음 첫 번째로 유지되는 일치 항목에 추출 (그룹 (1))을 적용하면 중복 적용이 방지됩니다.

2

대체 버전, 추출기로 정규식을 사용하여 :

val cfg: java.io.File = new java.io.File("temp.txt") 
val regexp = """jUnitVersion=(.*)""".r 
val version = scala.io.Source.fromFile(cfg) 
    .getLines() 
    .collectFirst { case regexp(value) => value } 
    .getOrElse("NOTFOUND") 
+1

'collectFirst' – Dima

+0

@Dima 감사합니다. 훨씬 좋네요. – Mikesname

1

표준 프로퍼티 파일처럼 외모를 분석하고 파일, 그래서 정규 표현식 장난에 대한 대안은 자바를 사용하는 것입니다 내장 java.util.Properties 파싱 :

+2

+1. 한 번이라도 정규 표현식을 적용해도 기꺼이하지 않을 것입니다. 정규 표현식이 확실히 자리를 잡고있는 동안, 이것은 그러한 상황 중 하나가 아닙니다. – Dave

+0

조언 해 주셔서 감사합니다.하지만 가능한 한 간단하게 예제를 유지하기 위해 속성 스타일 파일을 사용했습니다. 다양한 데이터 파일 (이전에는 perl 사용)에서 해킹을 많이하고, Scala에서 정규식을 가능한 간결하게 사용할 수있는 방법에 관심이 많습니다. – BarneyW

+0

@BarneyW 알겠습니다. 때로는 "최소한의 재현 가능한 예제"가 너무 작아 질 수 있다고 생각합니다.)이 간단한 사용 사례를 실제로 가지고있을 미래의 독자를 위해 여기를 남겨 두겠습니다. –

관련 문제