Steve McAffer
Steve McAffer

Reputation: 385

How to exclude a string from parsed text file using Scala?

A sample text file looks like this:

Date:  Nov 12, 2004
Support_Addresses:  [email protected], [email protected], 
                    [email protected], 
                    [email protected]
Notes:  Need to renew support contracts for software and services. 

Expected output is:

Nov 12, 2004
[email protected], [email protected], [email protected], [email protected] 
Need to renew support contracts for software and services. 

Basically, I need to exclude the field titles from the lines, so things like “Date:” , “Support_Addresses: “ and “Notes: “ are removed from the lines before they are saved to a CSV file. I have this code from other projects:

val support_agreements = lines
  .dropWhile(line => !line.startsWith("Support_Addresses: "))
  .takeWhile(line  => !line.startsWith(“Notes: "))
  .flatMap(_.split(","))
  .map(_.trim())
  .filter(_.nonEmpty)
  .mkString(", ")

But it does not remove the field titles/names. I am using startsWith, but it includes the field name. How can I exclude the field name from the line?

Upvotes: 0

Views: 153

Answers (2)

retrospectacus
retrospectacus

Reputation: 2586

Here's what I came up with. It builds a map of data m which could be manipulated usefully. This is then printed in the form you wanted.

def processValue(s: String): List[String] = 
  s.split(",").toList.map(_.trim).filterNot(_.isEmpty)

val retros = lines.foldLeft(List.empty[(String, List[String])]) {
  case (acc, l) =>
    l.indexOf(':') match {
      case -1 => 
        acc match {
          case Nil => acc // ???
          case h :: t => (h._1, h._2 ++ processValue(l)) :: t
        }
      case n =>
        val key = l.substring(0, n).trim
        val value = processValue(l.substring(n+1))
        (key, value) :: acc
    }
}

val m = retros.reverse.toMap

m.values.map(_.mkString(", ")).foreach(println)

Upvotes: 1

F. Lins
F. Lins

Reputation: 634

This should do it:

text.lines.map{ line =>
  line.indexOf(':') match {
    case x if x > 0 =>
      line.substring(x + 1).trim
    case _ => line.trim
  }
}.mkString("\n")

it iterates through the lines and if it finds a colon it calls the substring function

Upvotes: 1

Related Questions