Randomize
Randomize

Reputation: 9103

How to manage partial matching with regex?

I have a regex like this:

val myregex = "This is a (.*) text for (.*) and other thing like .*".r

If I run :

> val myregex(a,b) = "This is a test text for something and other thing like blah blah"
a: String = test
b: String = something

it is ok, and it fails is b is missing:

> val myregex(a,b) = "This is a test text for and other thing like blah blah"
scala.MatchError: This is a test text for and other thing like blah blah (of class java.lang.String)
  ... 33 elided

Is there a way to keep for example the value a and replace b with a fallback value (and viceversa)? Or the only solution is splitting the regex in two distincts regexs?

Upvotes: 2

Views: 302

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626835

Your original regex requires 2 consecutive spaces between for and and.

You may change your regex to actually match the string with an optional pattern by wrapping the space and the subsequent (.*) pattern with a non-capturing group and apply the ? quantifier to it making it optional:

val myregex = "This is a (.*) text for(?: (.*))? and other thing like .*".r
val x = "This is a test text for and other thing like blah blah"
x match {
    case myregex(a, b) => print(s"${a} -- ${b}");
    case _ => print("none")
}
// => test -- null

See the online Scala demo. Here, there is a match, but b is just null since the second capturing group did not participate in the match (and did not get initialized).

Upvotes: 2

OlivierBlanvillain
OlivierBlanvillain

Reputation: 7768

Or the only solution is splitting the regex in two distincts regexs?

This is the only solution. Your best bet is probably to use pattern matching:

("This is a test text for something", "and other thing like blah blah") match {
  case (r1(a), r2(b)) => (a, b)
  case (r1(a), _)     => (a, "fallback")
}

Upvotes: 0

Related Questions