Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make non-capturing groups work in scala regexes when pattern matching

Tags:

regex

scala

As far as I can see from the docs, non-capturing groups are defined by (:? ), as in Java. (I believe it's the same underlying library).

However, this doesn't seem to work:

var R = "a(:?b)c".r
R.findFirstMatchIn("abc").get.group(1)

returns "b" (when it should be empty). I suspect this is not normally a problem, but when doing pattern matching, it means that I can't now do:

"abc" match {case R => println("ok");case _ => println("not ok")}
> not ok

I have to do:

"abc" match {case R(x) => println("ok");case _ => println("not ok")}
> ok

Is there any way to make this work "as expected"?

like image 242
mo-seph Avatar asked Aug 13 '13 23:08

mo-seph


People also ask

What is the use of non-capturing group in regex?

Although they don't save the matched character sequence, non-capturing groups can alter pattern matching modifiers within the group. Some non-capturing groups can even discard backtracking information after a successful sub-pattern match.

What do you put at the start of a group to make it non-capturing?

Sometimes you want to use parentheses to group parts of an expression together, but you don't want the group to capture anything from the substring it matches. To do this use (?: and ) to enclose the group.

How do Capturing groups work in regex?

Capturing groups are a way to treat multiple characters as a single unit. They are created by placing the characters to be grouped inside a set of parentheses. For example, the regular expression (dog) creates a single group containing the letters "d" "o" and "g" .

What is regex in Scala?

Regular Expressions explain a common pattern utilized to match a series of input data so, it is helpful in Pattern Matching in numerous programming languages. In Scala Regular Expressions are generally termed as Scala Regex. Regex is a class which is imported from the package scala. util. matching.


1 Answers

In addition to the correct answer, use val and parens:

scala> val R = "a(?:b)c".r  // use val
R: scala.util.matching.Regex = a(?:b)c

scala> "abc" match {case R() => println("ok");case _ => println("not ok")} // parens not optional
ok

You can also always use the wildcard sequence and not care whether you specified capturing groups. I discovered this recently and find it is most clear and robust.

scala> "abc" match {case R(_*) => println("ok");case _ => println("not ok")} 
ok

If anything matches, _* will, including an extractor returning Some(null).

like image 184
som-snytt Avatar answered Nov 16 '22 03:11

som-snytt