4

I want to extract sub-strings from a string by using regular expressions in Scala.

For example, the string

line = "[129]: (29) -> (1): Rumor"

I want extract three numbers and last sub-string ("Rumor") from line.

How do I implement it in scala?

Update:

Thanks @Shyamendra Solanki, it works now. But I have another problem. When I read a line from a file and parse this line using your regex, eclipse reports weird error (I have no idea what's wrong). But if I do not use it, no error is reported.

val pattern = """\[(\d+)\]:\s\((\d+)\)\s\W\W\s\((\d)\):\s(\w+)""".r // define regex
for(line: String <- Source.fromFile(f1).getLines()){
    val pattern(clock, from, to, msg) = line
    println(clock+", "+ from+", "+to+", msg")
}

error:

Exception in thread "AWT-EventQueue-0" scala.MatchError: [1]: (1) <- (0): Init([LNode;@1f18e146,Full@1a6dca9d) (of class java.lang.String)
    at TwoNodeQuery$$anon$1$$anonfun$1$$anonfun$apply$mcV$sp$2.apply(Analysis.scala:74)
    at TwoNodeQuery$$anon$1$$anonfun$1$$anonfun$apply$mcV$sp$2.apply(Analysis.scala:73)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at TwoNodeQuery$$anon$1$$anonfun$1.apply$mcV$sp(Analysis.scala:73)
    at scala.swing.Action$$anon$2.apply(Action.scala:60)
    at scala.swing.Action$$anon$1.actionPerformed(Action.scala:78)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6505)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3312)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:708)
    at java.awt.EventQueue$4.run(EventQueue.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

2 Answers 2

4
val re = """\[(\d+)\]:\s\((\d+)\)\s\W\W\s\((\d)\):\s(\S+)""".r // define regex 
val s = "[129]: (29) -> (1): Rumor"   // line to match
val re(n1, n2, n3, s1) = s            // pattern match and extract values
(n1.toInt, n2.toInt, n3.toInt, s1)    // convert to expected types
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, your answer is right. But I have another problem now. I update my problem.
@city - The MatchError means that one of your lines didn't match the regexp, which made the destructuring-assignment (val pattern(clock, from, to, msg) = ...) fail.
In the line "[1]: (1) <- (0): Init<.....>" It appears that your last string contains non-word characters. You may try updating regex: from \w+ to \S+.
2

Starting Scala 2.13, it's possible to pattern match a Strings by unapplying a string interpolator:

val s"[$n1]: ($n2) -> ($n3): $rumor" = "[129]: (29) -> (1): Rumor"
n1: String = 129
n2: String = 29
n3: String = 1
rumor: String = Rumor

Note that we can also use regexes within the extractor.

Thus, in order to force the first 3 numbers to be valid integers:

val Nbr = "(\\d+)".r

"[129]: (29) -> (1): Rumor" match {
  case s"[${Nbr(n1)}]: (${Nbr(n2)}) -> (${Nbr(n3)}): $rumor" =>
    Some(n1.toInt, n2.toInt, n3.toInt, rumor)
  case _ => None
}
// Option[(Int, Int, Int, String)] = Some((129,29,1,Rumor))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.