сопоставить строку на основе соответствия шаблону регулярного выражения - PullRequest
0 голосов
/ 11 октября 2018

Я написал следующее регулярное выражение:

val reg = ".+([A-Z_].+).(\\d{4})_(\\d{2})_(\\d{2})_(\\d{2})\\.orc".r 

, которое должно анализировать следующие строки: "S3 // bucket // TS11_YREDED.2018_09_28_02.orc": метод анализа:

val dataExtraction: String => Map[String, String] = {
  string: String => {
    string match {
      case reg(filename, year, month, day) =>
                 Map(FILE_NAME-> filename, YEAR -> year, MONTH -> month, DAY -> day)
      case _  => Map(FILE_NAME-> filename,YEAR -> "", MONTH -> "", DAY -> "")
    }
  }
}
val YEAR = "YEAR"
val MONTH = "MONTH"
val DAY = "DAY"
val FILE_NAME = "FILE_NAME"

, но он не работает должным образом, предполагается, что он пропускает имя сегмента и синтаксический анализ имени файла и даты

, поэтому ожидаемый результат будет: Map (FILE_NAME-> TS11_YREDED, YEAR ->, MONTH-> 09, ДЕНЬ -> 28) Любая идея, как это исправить, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Проверьте это:

val file_name = "TS11_YREDED.2018_09_28_02.orc"
val reg = """(.*?)\.(\d{4})_(\d{2})_(\d{2})_(\d{2})\.orc""".r
var file_details = scala.collection.mutable.ArrayBuffer[String]()
reg.findAllIn(file_name).matchData.foreach( m => file_details.appendAll(m.subgroups))
val names=Array("FILE_NAME","YEAR","MONTH","DAY","DUMMY")
for( (x,y) <- names.zip(file_details).toMap)
  println(x + "->" + y)

//DUMMY->02
//DAY->28
//FILE_NAME->TS11_YREDED
//MONTH->09
//YEAR->2018
0 голосов
/ 11 октября 2018

Часть шаблона .+ сначала совпадает со всей строкой, а ([A-Z_].+) захватывает только то, что остается для захвата и сопоставления с последующими шаблонами.

Вы можете использовать

"""(?:.*/)?(.*)\.(\d{4})_(\d{2})_(\d{2})_\d{2}\.orc""".r

См. эту демонстрационную версию регулярного выражения

Обратите внимание, что точка должна быть экранирована, чтобы соответствовать буквальной точке.

Подробности

  • (?:.*/)? - любые 0+ символов, кроме символов разрыва строки, до максимально возможного числа, вплоть до последнего / и включая его
  • (.*) - Группа захвата 1: любые 0+ символов, кроме символов перевода строки, как можно больше
  • \. - точка
  • (\d{4}) - Группа захвата 2: четыре цифры
  • _ - знак подчеркивания
  • (\d{2}) - Группа захвата 3: две цифры
  • _ - знак подчеркивания
  • (\d{2}) - Группа захвата 4: две цифры
  • _\d{2}\.orc - _, 2 цифры, . и orc в конце строки.

Scala demo :

val text = "S3//bucket//TS11_YREDED.2018_09_28_02.orc"
val reg = """(?:.*/)?(.*)\.(\d{4})_(\d{2})_(\d{2})_\d{2}\.orc""".r

var YEAR = "YEAR"
var MONTH = "MONTH"
var DAY = "DAY"
var FILE_NAME = "FILE_NAME"

val dataExtraction: String => Map[String, String] = {
  string: String => {
    string match {
      case reg(filename, year, month, day) =>
                 Map(FILE_NAME-> filename, YEAR -> year, MONTH -> month, DAY -> day)
      case _  => Map(FILE_NAME-> FILE_NAME,YEAR -> YEAR, MONTH -> MONTH, DAY -> DAY)
    }
  }
}

println(dataExtraction(text))
// => Map(FILE_NAME -> TS11_YREDED, YEAR -> 2018, MONTH -> 09, DAY -> 28)

Поскольку вы не используете последнюю группу захвата, ее можно исключить из шаблона.

...