You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于文件模式使用Scala重构并格式化文本文件

Scala Solution for Reformatting Unstructured Text Files

Let's walk through how to parse and reformat your messy input text into a clean, structured format using Scala. Here's a step-by-step approach tailored to your sample content:

1. Define Data Structures

First, let's model the data we're working with using case classes—this makes it easy to handle structured data once we parse the raw text:

case class Review(
  title: String,
  firstName: String,
  lastName: String,
  country: String,
  date: String,
  rating: Int,
  text: String,
  productType: String,
  productId: String
)

case class Metadata(
  customerType: String,
  cabinFlown: String,
  route: String,
  dateFlown: String,
  seatComfort: String,
  cabinStaffService: String
)

2. Write Parsing Logic with Regular Expressions

The input text has distinct patterns we can target with regex. Let's create patterns to match both the review entries and the metadata fields:

object TextFormatter {
  // Pattern for matching review entries (handles the core review structure)
  private val reviewPattern = """\"([^\"]+)\" (\w+) (\w+) \((\w+)\) (\d+\w+ \w+ \d{4}) (\d+) (.+?) (\w+) (\w+-\d+)""".r
  // Patterns for extracting metadata fields
  private val customerTypePattern = """Type Of Customer ([\w ]+)""".r
  private val cabinFlownPattern = """Cabin Flown (\w+)""".r
  private val routePattern = """Route (\w+ to \w+)""".r
  private val dateFlownPattern = """Date Flown (\w+ \d{4})""".r
  private val seatComfortPattern = """Seat Comfort (\d+)""".r
  private val cabinStaffServicePattern = """Cabin Staff Service (\d+)""".r

  def parseRawText(rawText: String): (List[Review], Metadata) = {
    // Extract all review entries from the raw text
    val reviews = reviewPattern.findAllMatchIn(rawText).map { m =>
      Review(
        title = m.group(1),
        firstName = m.group(2),
        lastName = m.group(3),
        country = m.group(4),
        date = m.group(5),
        rating = m.group(6).toInt,
        text = m.group(7).trim,
        productType = m.group(8),
        productId = m.group(9)
      )
    }.toList

    // Extract metadata fields (fallback to "Unknown" if a field is missing)
    val customerType = customerTypePattern.findFirstMatchIn(rawText).map(_.group(1)).getOrElse("Unknown")
    val cabinFlown = cabinFlownPattern.findFirstMatchIn(rawText).map(_.group(1)).getOrElse("Unknown")
    val route = routePattern.findFirstMatchIn(rawText).map(_.group(1)).getOrElse("Unknown")
    val dateFlown = dateFlownPattern.findFirstMatchIn(rawText).map(_.group(1)).getOrElse("Unknown")
    val seatComfort = seatComfortPattern.findFirstMatchIn(rawText).map(_.group(1)).getOrElse("Unknown")
    val cabinStaffService = cabinStaffServicePattern.findFirstMatchIn(rawText).map(_.group(1)).getOrElse("Unknown")

    val metadata = Metadata(customerType, cabinFlown, route, dateFlown, seatComfort, cabinStaffService)

    (reviews, metadata)
  }
}

3. Format the Parsed Data into the Desired Output

Now that we have structured data, let's convert it into the clean, readable format you need:

def formatOutput(reviews: List[Review], metadata: Metadata): String = {
  // Format each review into the specified line structure
  val reviewsSection = reviews.map { review =>
    s""""${review.title}" ${review.firstName} ${review.lastName} (${review.country})
       |${review.date} ${review.rating}
       |${review.text}
       |${review.productType} ${review.productId}
       |""".stripMargin
  }.mkString("\n")

  // Format metadata into a clear, labeled section
  val metadataSection = s"""Type Of Customer: ${metadata.customerType}
                           |Cabin Flown: ${metadata.cabinFlown}
                           |Route: ${metadata.route}
                           |Date Flown: ${metadata.dateFlown}
                           |Seat Comfort: ${metadata.seatComfort}
                           |Cabin Staff Service: ${metadata.cabinStaffService}""".stripMargin

  // Combine sections with a divider
  s"$reviewsSection\n---\n$metadataSection"
}

4. Putting It All Together

To use this with your text file, read the file content, parse it, then format and output the result:

import scala.io.Source

def main(args: Array[String]): Unit = {
  // Read raw text from your input file
  val rawText = Source.fromFile("your-input-file.txt").mkString
  // Parse into structured data
  val (reviews, metadata) = TextFormatter.parseRawText(rawText)
  // Generate formatted output
  val formattedText = formatOutput(reviews, metadata)
  
  // Print to console or write to a new file
  println(formattedText)
  // To write to a file:
  // import java.io.PrintWriter
  // new PrintWriter("formatted-output.txt") { write(formattedText); close() }
}

Example Formatted Output

Using your sample input, the output will look like this:

"good service" Tom Martin (USA)
17th October 2015 4
Hi my name is Tom. I love boardgames.
Aircraft TXT-102

"not bad" M Muller (Canada)
22nd September 2015 6
Hi I like boardgames.
Aircraft TXT-101


Type Of Customer: Couple Leisure
Cabin Flown: FirstClass
Route: IND to CHI
Date Flown: September 2015
Seat Comfort: 12345
Cabin Staff Service: 12345

Quick Adjustments for Edge Cases

  • If names have more than two parts (e.g., "Mary Ann Smith"), tweak the review regex to capture full names with ([\w ]+) instead of separate first/last groups.
  • If the input has inconsistent whitespace, add \s+ in the regex patterns to handle variable spacing between fields.

内容的提问来源于stack exchange,提问作者jOasis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:16:21