test solo regulares regular regexp probar numeros expresiones expresion example especiales espacio ejemplos caracteres blanco alfanumerico regex scala pattern-matching

regex - solo - probar expresiones regulares



¿Cómo se empareja el patrón usando expresiones regulares en Scala? (7)

Me gustaría poder encontrar una coincidencia entre la primera letra de una palabra y una de las letras de un grupo como "ABC". En pseudocódigo, esto podría ser algo así como:

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

¿Pero cómo agarro la primera letra en Scala en vez de Java? ¿Cómo expreso la expresión regular correctamente? ¿Es posible hacer esto dentro de una clase de caso ?


Como señaló Delnan, la palabra clave de match en Scala no tiene nada que ver con las expresiones regulares. Para saber si una cadena coincide con una expresión regular, puede usar el método String.matches . Para saber si una cadena comienza con a, boc en mayúscula o minúscula, la expresión regular se vería así:

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

Puede leer esta expresión regular como "uno de los caracteres a, b, c, A, B o C seguidos de cualquier elemento" ( . Significa "cualquier carácter" y * significa "cero o más veces", por lo que ". *" Es cualquier cuerda).


Desde la versión 2.10, se puede usar la función de interpolación de cadenas de Scala:

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

Aún mejor, uno puede unir grupos de expresiones regulares:

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

También es posible establecer mecanismos de enlace más detallados:

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

Un ejemplo impresionante de lo que es posible con Dynamic se muestra en la entrada del blog Introducción al tipo dinámico :

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") } }


Para ampliar un poco la respuesta de Andrew : El hecho de que las expresiones regulares definan extractores se puede usar para descomponer las subcadenas emparejadas por la expresión regular muy bien usando la coincidencia de patrones de Scala, por ejemplo:

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. }


Primero debemos saber que la expresión regular puede usarse por separado. Aquí hay un ejemplo:

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

En segundo lugar, debemos observar que la combinación de expresión regular con la coincidencia de patrones sería muy poderosa. Aquí hay un ejemplo simple.

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

De hecho, la expresión regular en sí misma ya es muy poderosa; lo único que tenemos que hacer es hacerlo más poderoso por Scala. Aquí hay más ejemplos en el documento de Scala: http://www.scala-lang.org/files/archive/api/current/index.html#scala.util.matching.Regex


Puede hacer esto porque las expresiones regulares definen extractores pero primero debe definir el patrón de expresiones regulares. No tengo acceso a un Scala REPL para probar esto, pero algo así debería funcionar.

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


String.matches es la forma de hacer coincidencias de patrones en el sentido de expresiones regulares.

Pero como un lado útil, Word.firstLetter en código Scala real se ve así:

word(0)

Scala trata a Strings como una secuencia de Char, así que si por alguna razón quisieras obtener explícitamente el primer personaje de String y unirlo, podrías usar algo como esto:

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

No estoy proponiendo esto como la manera general de hacer la coincidencia de patrón de expresiones regex, pero está en línea con su enfoque propuesto para encontrar primero el primer carácter de una Cadena y luego hacerla coincidir con una expresión regular.

EDITAR: Para ser claro, la forma en que lo haría es, como otros han dicho:

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

Solo quería mostrar un ejemplo lo más cercano posible a su pseudocódigo inicial. ¡Aclamaciones!


Tenga en cuenta que el enfoque de la respuesta de @MaryMyers coincide con la cadena completa a la expresión regular, con el efecto de anclar la expresión regular en ambos extremos de la cadena usando ^ y $ . Ejemplo:

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

Y con no .* Al final:

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