Parse String для создания объектов с использованием Regex в Scala - PullRequest
0 голосов
/ 15 октября 2019

У меня есть входной список строк, который я хотел бы перевести в список объектов с помощью регулярных выражений. В приведенном ниже коде я не создаю объекты, а печатаю их в stdout для простоты.

Я могу поддерживать некоторые входные строки, но не весь список. Может кто-нибудь поделится, что я делаю не так?

  lazy val TIMESTAMP_PATTERN: Regex = """(year|month|day|hour)\(([a-zA-Z_]+)[,]?([a-zA-Z_]*)\)""".r
  lazy val BUCKET_PATTERN: Regex = """(bucket)\((.+)(,)(.+)[,]?(.*)\)""".r

  Seq(
    "year(timestamp)",
    "year(timestamp, _MY_YEAR)",
    "month(timestamp)",
    "month(timestamp, _MY_MONTH)",
    "day(timestamp)",
    "day(timestamp, _MY_DAY)",
    "hour(timestamp)",
    "hour(timestamp, _MY_HOUR)",
    "bucket(id, 32)",
    "bucket(id, 32, _MY_BUCKET)",
  ).foreach { input => input match {
      case TIMESTAMP_PATTERN(transform, sourceColumn, targetColumn) => println(s"$transform ::: $sourceColumn :::- $targetColumn")
      case BUCKET_PATTERN(sourceColumn, numBuckets) => println(s"bucket ::: $sourceColumn ::: $numBuckets")
      case BUCKET_PATTERN(sourceColumn, numBuckets, targetColumn) => println(s"bucket ::: $sourceColumn ::: $numBuckets ::: $targetColumn")
      case z => println(s"Unexpected match: $z")
    }
  }

Вывод

year ::: timestamp :::- 
Unexpected match: year(timestamp, _MY_YEAR)
month ::: timestamp :::- 
Unexpected match: month(timestamp, _MY_MONTH)
day ::: timestamp :::- 
Unexpected match: day(timestamp, _MY_DAY)
hour ::: timestamp :::- 
Unexpected match: hour(timestamp, _MY_HOUR)
Unexpected match: bucket(id, 32)
Unexpected match: bucket(id, 32, _MY_BUCKET)

1 Ответ

0 голосов
/ 15 октября 2019

Я сделал несколько исправлений в ваших регулярных выражениях и соответствовал:

lazy val TIMESTAMP_PATTERN: Regex = """(year|month|day|hour)\((\w+)(?:,\s+)?(\w*)\)""".r
lazy val BUCKET_PATTERN: Regex = """bucket\((\w+),(?:\s+)?(\w+)(?:,\s+)?(\w*)\)""".r

  Seq(
    "year(timestamp)",
    "year(timestamp, _MY_YEAR)",
    "month(timestamp)",
    "month(timestamp, _MY_MONTH)",
    "day(timestamp)",
    "day(timestamp, _MY_DAY)",
    "hour(timestamp)",
    "hour(timestamp, _MY_HOUR)",
    "bucket(id, 32)",
    "bucket(id, 32, _MY_BUCKET)",
  ).foreach {
    case TIMESTAMP_PATTERN(transform, sourceColumn, "") => println(s"$transform ::: $sourceColumn")
    case TIMESTAMP_PATTERN(transform, sourceColumn, targetColumn) => println(s"$transform ::: $sourceColumn :::- $targetColumn")
    case BUCKET_PATTERN(sourceColumn, numBuckets, "") => println(s"bucket ::: $sourceColumn ::: $numBuckets")
    case BUCKET_PATTERN(sourceColumn, numBuckets, targetColumn) => println(s"bucket ::: $sourceColumn ::: $numBuckets ::: $targetColumn")
    case z => println(s"Unexpected match: $z")
  }

Теперь вывод:

year ::: timestamp
year ::: timestamp :::- _MY_YEAR
month ::: timestamp
month ::: timestamp :::- _MY_MONTH
day ::: timestamp
day ::: timestamp :::- _MY_DAY
hour ::: timestamp
hour ::: timestamp :::- _MY_HOUR
bucket ::: id ::: 32
bucket ::: id ::: 32 ::: _MY_BUCKET

Вот изменения, которые я сделал:

  • Добавлено ?: в группы, состоящие из , s и пробелов, чтобы сделать эти группы не захватывающими. При использовании этого метода пробелы все еще являются необязательными, но они не влияют на сопоставление конца.
  • Removed () из bucket , поэтому это не группа захвата
  • , посколькуПоследнее совпадение является необязательным и может быть пустым, изменив шаблон с меньшим количеством элементов, чтобы соответствовать этому случаю. Обратите внимание, что если последний столбец отсутствует, его группа захвата будет пустой.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...