문자열이 Scala의 Regex와 완전히 일치하는지 확인하는 방법은 무엇입니까?


80

많은 문자열을 일치시키고 싶은 정규식 패턴이 있다고 가정합니다.

val Digit = """\d""".r

주어진 문자열이 정규식과 완전히 일치하는지 확인하고 싶습니다. Scala에서 이것을 수행하는 좋고 관용적 인 방법은 무엇입니까?

정규식에서 패턴 일치를 수행 할 수 있다는 것을 알고 있지만 추출 할 그룹이 없기 때문에이 경우 구문 상별로 만족스럽지 않습니다.

scala> "5" match { case Digit() => true case _ => false }
res4: Boolean = true

또는 기본 Java 패턴으로 돌아갈 수 있습니다.

scala> Digit.pattern.matcher("5").matches
res6: Boolean = true

우아하지도 않습니다.

더 나은 해결책이 있습니까?


"5" match { case Digit() => true case _ => false }기본 패턴 객체를 사용하는 것보다 더 좋아 보인다고 생각 합니다.
Mygod

답변:


66

내 질문에 답하기 위해 "포주 내 라이브러리 패턴"을 사용하겠습니다.

object RegexUtils {
  implicit class RichRegex(val underlying: Regex) extends AnyVal {
    def matches(s: String) = underlying.pattern.matcher(s).matches
  }
}

이렇게 사용하세요

import RegexUtils._
val Digit = """\d""".r
if (Digit matches "5") println("match")
else println("no match")

누군가가 더 나은 (표준) 솔루션을 제시하지 않는 한.

메모

  • 나는 String잠재적 인 부작용의 범위를 제한 하지 않았습니다 .

  • unapplySeq 그 맥락에서 잘 읽히지 않습니다.


염두에 둔 특별한 부작용이 있습니까? 나는 String대신 포주 를했고 지금까지 String의 멤버 함수 에도 불구하고 잘 작동합니다 matches(regex: String).
KajMagnus 2012

1
나는 기능 misses도 가지고 있었다. Match and missmatch :-) !s.matches(r)대신 작성해야하는 것은 너무 귀찮습니다 s misses r. 흠
KajMagnus

1
"5" matches "\\d"@polygenelubricants가 제안한 내장 기능은 어떻습니까?
Erik Kaplun 2014

2
데이터는 패턴과 일치하며 그 반대가 아닙니다. Regex의 scaladoc은 "일치"에 대한 부울 부족에 대해 큰 문제를 일으 킵니다. 개인적으로, 나는 당신이 더 투박한 if-else로 멋진 경기를 바꿨다고 생각합니다. 그룹에 관심이 없다면 case r(_*) =>.
som-snytt 2014 년

... 외부 라이브러리를 가져 오지 않고 할 수있는 방법이 있어야한다
Jameela Huq에게

56

저는 Scala를 잘 모르지만 다음과 같이 할 수 있습니다.

"5".matches("\\d")

참고 문헌


25
음, 작동하지만 일치하려고 할 때마다 패턴이 컴파일된다는 단점이 있습니다. 성능상의 이유로 그것을 피하고 싶습니다.
mkneissl 2010 년

3
@mkneissl : 그러면 당신 .pattern.matcher(text).matches이 갈 길인 것 같습니다 . 일부 유틸리티 메서드 나 오버로드 된 연산자 또는 Scala가 지원하는 경우에는 자세한 내용을 숨길 수 있습니다.
polygenelubricants 2010 년

4
고마워, 그게 내가 할 일입니다. 내 대답을 참조하십시오. 나는 메타 그것이 ... 말한다 ... 스택 오버플로에 동작을 받아 들여 자신의 질문에 대답 희망
mkneissl

2
@ed. 그게 더 느리고 더 까다 롭습니다. 왜 그렇습니까?
Erik Kaplun 2014

참고로 주어진 링크가 깨진
VALY 디아를

13

전체 일치를 위해 unapplySeq를 사용할 수 있습니다 . 이 메서드는 대상 (전체 일치) 일치를 시도하고 일치 항목을 반환합니다.

scala> val Digit = """\d""".r
Digit: scala.util.matching.Regex = \d

scala> Digit unapplySeq "1"
res9: Option[List[String]] = Some(List())

scala> Digit unapplySeq "123"
res10: Option[List[String]] = None

scala> Digit unapplySeq "string"
res11: Option[List[String]] = None

4
사실이지만 unapply 및 unapplySeq의 주요 사용은 암시 적 case으로 match블록 의 s에 있습니다.
Randall Schulz

11
  """\d""".r.unapplySeq("5").isDefined            //> res1: Boolean = true
  """\d""".r.unapplySeq("a").isDefined            //> res2: Boolean = false

흠. 2 년 후 stackoverflow.com/a/3022478/158823 의 사본을 게시하는 이유는 무엇 입니까?
mkneissl

2
원래 질문은 '일부'또는 '없음'이 아닌 '참'또는 '거짓'으로 끝나는 결과를 요청했습니다. 내가 아는 한 isDefined는 2 년 전에 도서관의 일부가 아니었지만 아마도 그랬을 것입니다. 어쨌든, 내 대답은 중복되지 않습니다 ;-)
Jack

중복되지 않습니다. 죄송합니다.
mkneissl

1
아니 문제 ;-) 내 실수, 내 대답에서 isDefined를 사용하는 이유를 설명해야했습니다. 대답으로 코드를 제공하는 것은 일반적으로 나쁜 생각이므로 내 잘못입니다.
Jack

1

대답은 정규식에 있습니다.

val Digit = """^\d$""".r

그런 다음 기존 방법 중 하나를 사용하십시오.


3
나는 앵커가 여기서 문제라고 생각하지 않습니다. String/Pattern/Matcher.matches, 적어도 Java에서는 이미 전체 문자열 일치입니다. 나는 문제가 스칼라에서 정규식을위한 스타일 / 관용구, 즉 "기존 방법 중 하나"가 무엇인지라고 생각한다.
polygenelubricants 2010-06-12

@polygenelubricants 음, Matcher.matches수차입니다. 좋아, 자바 라이브러리가 실제로 그것을 활용하는지 모르겠지만 몇 가지 최적화가 가능합니다. 그러나 정규 표현식에서 전체 일치가 필요함을 표현하는 표준 방법은 앵커를 사용하는 것입니다. Scala 라이브러리는 전체 일치 방법을 제공 하지 않으므로 이를 수행하는 적절한 방법은 앵커를 사용하는 것입니다. 또는 Java 라이브러리를 사용하십시오.
Daniel C. Sobral 2010-06-14

고정은 문제가 아닙니다. Vasil의 답변에서 "123"예제를 참조하십시오.
mkneissl

5
@Daniel 당신은 요점을 놓치고있을 수 있습니다. 제 질문은 정규식이 완전히 일치하는지 알 필요가 있다면 Scala에서 그것을 표현하는 좋은 방법이 무엇인지였습니다. 작동하는 솔루션이 많이 있지만 요약하면 Regex에 누락 된 방법이 있고 다른 작업은 수행하지 않는다고 생각합니다. 귀하의 의견에 대한 질문에 답하려면 unapplySeq와 findFirstMatch의 차이점은 앵커를 추가하기 위해 Regex를 변경해야한다는 것입니다. 두 방법 모두 내 의도를 즉시 표현하지도 않고 부울 값을 반환하지도 않습니다. 즉, Option에서 Boolean으로 이동해야합니다 (문제는 없지만 더 복잡하게 추가됨).
mkneissl

1
@mkneissl Java의 개념이 싫지만 matches괜찮습니다. Optionvs에 관해서 는 끝에 Boolean추가 nonEmpty하면 Boolean.
Daniel C. Sobral 2010-06-15

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.