복붙노트

[SCALA] 스칼라에서 정규 표현식을 사용하는 방법 패턴 일치에?

SCALA

스칼라에서 정규 표현식을 사용하는 방법 패턴 일치에?

나는 첫 번째 단어의 문자 및 "ABC"와 같은 그룹에있는 문자 중 하나와 일치하는 항목을 찾을 수 있도록하고 싶습니다. 의사,이 뭔가를 같이 보일 수 있습니다 :

case Process(word) =>
   word.firstLetter match {
      case([a-c][A-C]) =>
      case _ =>
   }
}

그러나 어떻게 스칼라 대신 자바의 첫 글자를 잡아합니까? 어떻게 제대로 정규 표현식을 표현합니까? 이 경우 클래스 내에서이 작업을 수행 할 수 있습니까?

해결법

  1. ==============================

    1.정규 표현식 추출기를 정의하지만, 먼저 정규식 패턴을 정의 할 필요가 있기 때문에이 작업을 수행 할 수 있습니다. 나는이 테스트를 위해 스칼라 REPL에 액세스 할 수없는 그러나이 같은 작업을해야합니다.

    정규 표현식 추출기를 정의하지만, 먼저 정규식 패턴을 정의 할 필요가 있기 때문에이 작업을 수행 할 수 있습니다. 나는이 테스트를 위해 스칼라 REPL에 액세스 할 수없는 그러나이 같은 작업을해야합니다.

    val Pattern = "([a-cA-C])".r
    word.firstLetter match {
       case Pattern(c) => c bound to capture group here
       case _ =>
    }
    
  2. ==============================

    2.버전 2.10 이후, 하나는 스칼라의 문자열 보간 기능을 사용할 수 있습니다 :

    버전 2.10 이후, 하나는 스칼라의 문자열 보간 기능을 사용할 수 있습니다 :

    implicit class Regex(sc: StringContext) {
      def r = new util.matching.Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
    }
    
    scala> "123" match { case r"\d+" => true case _ => false }
    res34: Boolean = true
    

    더 좋은 점 하나는 정규 표현식 그룹을 결합 할 수있다 :

    scala> "123" match { case r"(\d+)$d" => d.toInt case _ => 0 }
    res36: Int = 123
    
    scala> "10+15" match { case r"(\d\d)${first}\+(\d\d)${second}" => first.toInt+second.toInt case _ => 0 }
    res38: Int = 25
    

    더 자세한 바인딩 메커니즘을 설정하는 것도 가능합니다 :

    scala> object Doubler { def unapply(s: String) = Some(s.toInt*2) }
    defined module Doubler
    
    scala> "10" match { case r"(\d\d)${Doubler(d)}" => d case _ => 0 }
    res40: Int = 20
    
    scala> object isPositive { def unapply(s: String) = s.toInt >= 0 }
    defined module isPositive
    
    scala> "10" match { case r"(\d\d)${d @ isPositive()}" => d.toInt case _ => 0 }
    res56: Int = 10
    

    동적으로 무엇이 가능한지에 대한 인상적인 예는 동적을 입력 할 수있는 블로그 게시물의 소개에 표시됩니다 :

    object T {
    
      class RegexpExtractor(params: List[String]) {
        def unapplySeq(str: String) =
          params.headOption flatMap (_.r unapplySeq str)
      }
    
      class StartsWithExtractor(params: List[String]) {
        def unapply(str: String) =
          params.headOption filter (str startsWith _) map (_ => str)
      }
    
      class MapExtractor(keys: List[String]) {
        def unapplySeq[T](map: Map[String, T]) =
          Some(keys.map(map get _))
      }
    
      import scala.language.dynamics
    
      class ExtractorParams(params: List[String]) extends Dynamic {
        val Map = new MapExtractor(params)
        val StartsWith = new StartsWithExtractor(params)
        val Regexp = new RegexpExtractor(params)
    
        def selectDynamic(name: String) =
          new ExtractorParams(params :+ name)
      }
    
      object p extends ExtractorParams(Nil)
    
      Map("firstName" -> "John", "lastName" -> "Doe") match {
        case p.firstName.lastName.Map(
              Some(p.Jo.StartsWith(fn)),
              Some(p.`.*(\\w)$`.Regexp(lastChar))) =>
          println(s"Match! $fn ...$lastChar")
        case _ => println("nope")
      }
    }
    
  3. ==============================

    3.delnan가 지적한 바와 같이, 스칼라의 검색 키워드는 정규 표현식에 함께 할 수 없다. 문자열이 정규식과 일치하는지 여부를 확인하려면, 당신은 String.matches 방법을 사용할 수 있습니다. 문자열이 낮거나 대문자의 A, B 또는 C로 시작하는지 여부를 확인하기 위해, 정규식은 다음과 같이 보일 것이다 :

    delnan가 지적한 바와 같이, 스칼라의 검색 키워드는 정규 표현식에 함께 할 수 없다. 문자열이 정규식과 일치하는지 여부를 확인하려면, 당신은 String.matches 방법을 사용할 수 있습니다. 문자열이 낮거나 대문자의 A, B 또는 C로 시작하는지 여부를 확인하기 위해, 정규식은 다음과 같이 보일 것이다 :

    word.matches("[a-cA-C].*")
    

    넌. "임의의 문자"를 의미하고, * 그래서 "0 번 이상"을 의미 ( "A, B, C, A, B 문자 중 하나 또는 C 아무것도 뒤에"등이 정규 표현식을 읽을 수있다 ". *"임의이며 끈).

  4. ==============================

    4.앤드류의 대답에 조금 확장하려면 : 정규 표현식 추출기는 예컨대 스칼라의 패턴 매칭을 사용하여 아주 멋지게 정규식에 의해 일치하는 문자열을 분해하는 데 사용할 수있는 정의는 사실을 :

    앤드류의 대답에 조금 확장하려면 : 정규 표현식 추출기는 예컨대 스칼라의 패턴 매칭을 사용하여 아주 멋지게 정규식에 의해 일치하는 문자열을 분해하는 데 사용할 수있는 정의는 사실을 :

    val Process = """([a-cA-C])([^\s]+)""".r // define first, rest is non-space
    for (p <- Process findAllIn "aha bah Cah dah") p match {
      case Process("b", _) => println("first: 'a', some rest")
      case Process(_, rest) => println("some first, rest: " + rest)
      // etc.
    }
    
  5. ==============================

    5.String.matches는 정규식 의미에서 패턴 매칭을 할 수있는 방법입니다.

    String.matches는 정규식 의미에서 패턴 매칭을 할 수있는 방법입니다.

    그러나 옆 편리한로, 실제 스칼라 코드 word.first 편지는 다음과 같습니다

    word(0)
    

    스칼라는 샤아의 순서로 문자열을 취급, 그래서 어떤 이유로 당신이 명시 적으로 문자열의 첫 번째 문자를 얻고 일치하기를 원한다면, 다음과 같이 사용할 수 있습니다 :

    "Cat"(0).toString.matches("[a-cA-C]")
    res10: Boolean = true
    

    나는 정규식 패턴 매칭을 수행하는 일반적인 방법으로이 제안 아니지만, 먼저 문자열의 첫 번째 문자를 찾은 다음 정규식에 대해 그것을 일치하도록 제안 된 접근 방식과 일치합니다.

    편집하다: 다른 사람이 말했듯이 명확하게하기 위해, 내가 이런 짓을 했을까 방법이 있습니다 :

    "Cat".matches("^[a-cA-C].*")
    res14: Boolean = true
    

    그냥 초기 의사에 가능한 한 가까운 예를 보여주고 싶었다. 건배!

  6. ==============================

    6.AndrewMyers의 대답 @의 접근 방식이 사용하는 문자열 ^ 및 $의 양쪽 끝에서 정규 표현식을 고정의 효과, 정규 표현식에 전체 문자열과 일치합니다. 예:

    AndrewMyers의 대답 @의 접근 방식이 사용하는 문자열 ^ 및 $의 양쪽 끝에서 정규 표현식을 고정의 효과, 정규 표현식에 전체 문자열과 일치합니다. 예:

    scala> val MY_RE = "(foo|bar).*".r
    MY_RE: scala.util.matching.Regex = (foo|bar).*
    
    scala> val result = "foo123" match { case MY_RE(m) => m; case _ => "No match" }
    result: String = foo
    
    scala> val result = "baz123" match { case MY_RE(m) => m; case _ => "No match" }
    result: String = No match
    
    scala> val result = "abcfoo123" match { case MY_RE(m) => m; case _ => "No match" }
    result: String = No match
    

    그리고 아니 * 끝. :

    scala> val MY_RE2 = "(foo|bar)".r
    MY_RE2: scala.util.matching.Regex = (foo|bar)
    
    scala> val result = "foo123" match { case MY_RE2(m) => m; case _ => "No match" }
    result: String = No match
    
  7. ==============================

    7.먼저 우리는 정규 표현식 별도로 사용될 수 있다는 것을 알아야한다. 다음은 그 예이다 :

    먼저 우리는 정규 표현식 별도로 사용될 수 있다는 것을 알아야한다. 다음은 그 예이다 :

    import scala.util.matching.Regex
    val pattern = "Scala".r // <=> val pattern = new Regex("Scala")
    val str = "Scala is very cool"
    val result = pattern findFirstIn str
    result match {
      case Some(v) => println(v)
      case _ =>
    } // output: Scala
    

    두 번째로 우리는 패턴 매칭으로 정규 표현식을 결합하는 것은 매우 강력 할 것이라는 점을주의해야합니다. 다음은 간단한 예이다.

    val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r
    "2014-11-20" match {
      case date(year, month, day) => "hello"
    } // output: hello
    

    사실, 정규 표현식 자체가 이미 매우 강력하다; 우리가해야 할 유일한 것은 스칼라에 의해 더 강력하게하는 것입니다. 다음은 스칼라 문서에서 더 많은 예제는 다음과 같습니다 http://www.scala-lang.org/files/archive/api/current/index.html#scala.util.matching.Regex

  8. from https://stackoverflow.com/questions/4636610/how-to-pattern-match-using-regular-expression-in-scala by cc-by-sa and MIT license