Как создать обобщенное регулярное выражение c, чтобы можно было извлечь весь результат группы в scala spark - PullRequest
1 голос
/ 01 февраля 2020

У нас есть файл журнала .txt, я использовал scala spark, чтобы прочитать файл. файл содержит наборы данных по строкам. я читаю данные по очереди, как показано ниже

val sc = spark.SparkContext
val dataframe = sc.textFile(/path/to/log/*.txt)

В основном данные во всех файлах журналов имеют три типа, как один из них, как показано ниже

ManagedElement=LNJ05193B,ENodeBFunction=1,RadioBearerTable=default,DataRadioBearer=1 dlMaxRetxThreshold 8   LNJ05193B   dlMaxRetxThreshold  8
ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=DNJ05024D31 enableServiceSpecificHARQ false DNJ05024D31 enableServiceSpecificHARQ   FALSE
ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=LNJ05024D31 primaryUpperLayerInd OFF    LNJ05024D31 primaryUpperLayerInd    OFF

и второй тип строки этот тип

ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=BNJ05024D31,EUtranFreqRelation=5035 connectedModeMobilityPrio 7 LNJ05024D   5035    connectedModeMobilityPrio

и некоторые необработанные строки, как показано ниже:

ManagedElement=LNJ05147D,ENodeBFunction=1,EUtranCellFDD=LNJ05147D11,EUtranFreqRelation=2250,EUtranCellRelation=310260-51992-1 cellIndividualOffsetEUtran 0  LNJ05147D11 2250    310260  cellIndividualOffsetEUtran  0

Я пытаюсь создать общий CSV-файл, содержащий все записи выше, как показано ниже

Во всех типах строк общей частью является Mana = и ENF =, поэтому для получения этого используется регулярное выражение, например

val regx_first_exp = """"Manag=(\w*).*ENF=(\w),.*""".r

Последние два слова - это значение ключа, которое можно извлечь, как показано ниже

val last_two = """(\w+)=(\w+[^=])"""".r

и в промежутке между ними я пытаюсь извлечь значение после eqal to (= знак) в другом и хочу поместить в разные столбцы, если нет совпадения, чем простое значение null в определенных столбцах.

Окончательный вариант, например:

+--------------+-----------+---------------+--------------+--------------------------+----------+
|managedElement|cellFDD    |targetFrequency|targetCell    |paramName                 |paramValue|
+--------------+-----------+---------------+--------------+--------------------------+----------+
|LNJ05025D     |DNJ05025D31|AWS_2087       |null          |threshXHighQ              |0         |
|LNJ05024D     |BNJ05024D31|5035           |null          |connectedModeMobilityPrio |7         |
|LNJ05193B     |null       |null           |null          |dlMaxRetxThreshold        |8         |
|LNJ05024D     |DNJ05024D31|null           |null          |enableServiceSpecificHARQ |false     |
|LNJ05024D     |LNJ05024D31|null           |null          |primaryUpperLayerInd      |OFF       |
|LNJ05147D     |LNJ05147D11|2250           |310260-51992-1|cellIndividualOffsetEUtran|0         |
+--------------+-----------+---------------+--------------+--------------------------+----------+

Можно ли это сделать в одной функции регулярного выражения или нескольких udf с минимальным фильтром?

Я новичок в scala, пожалуйста предоставить предложение для того же. последний столбец в изображении только для типа строк, как упомянуто одна за другой.

1 Ответ

1 голос
/ 01 февраля 2020

Вот одно решение, которое работает с 4 различными регулярными выражениями, используя сопоставление с образцом с регулярными выражениями, как объяснено здесь :

val df = Seq(
 ("ManagedElement=LNJ05025D,ENodeBFunction=1,EUtranCellFDD=DNJ05025D31,UtranFreqRelation=AWS_2087 threshXHighQ 0"),
 ("ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=BNJ05024D31,EUtranFreqRelation=5035 connectedModeMobilityPrio 7"),
 ("ManagedElement=LNJ05193B,ENodeBFunction=1,RadioBearerTable=default,DataRadioBearer=1 dlMaxRetxThreshold 8"),
 ("ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=DNJ05024D31 enableServiceSpecificHARQ false"),
 ("ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=LNJ05024D31 primaryUpperLayerInd OFF"),
 ("ManagedElement=LNJ05147D,ENodeBFunction=1,EUtranCellFDD=LNJ05147D11,EUtranFreqRelation=2250,EUtranCellRelation=310260-51992-1 cellIndividualOffsetEUtran 0")
).toDF("logs")

case class LogItem(managedElement: String, cellFDD: String, targetFrequency: String, targetCell: String, paramName: String, paramValue: String)

// 1st type: ManagedElement=LNJ05025D,ENodeBFunction=1,EUtranCellFDD=DNJ05025D31,UtranFreqRelation=AWS_2087 threshXHighQ 0
// extract 5 groups
val log1RegExpr = """^ManagedElement=(\w+).*EUtranCellFDD=(\w+).*tranFreqRelation=(\w+)\s(\w+)\s(\w+)$""".r

// 2nd type: ManagedElement=LNJ05193B,ENodeBFunction=1,RadioBearerTable=default,DataRadioBearer=1 dlMaxRetxThreshold 8
// extract 3 groups
val log2RegExpr = """^ManagedElement=(\w+).*\s(\w+)\s(\w+)$""".r

// 3rd type: ManagedElement=LNJ05024D,ENodeBFunction=1,EUtranCellFDD=DNJ05024D31 enableServiceSpecificHARQ false
// extract 4 groups
val log3RegExpr = """^ManagedElement=(\w+).*EUtranCellFDD=(\w+)\s(\w+)\s(\w+)$""".r

// 4th type: ManagedElement=LNJ05147D,ENodeBFunction=1,EUtranCellFDD=LNJ05147D11,EUtranFreqRelation=2250,EUtranCellRelation=310260-51992-1 cellIndividualOffsetEUtran 0
// extract 6 groups
val log4RegExpr = """^ManagedElement=(\w+).*EUtranCellFDD=(\w+).*tranFreqRelation=(\w+).*EUtranCellRelation=(\S+)\s(\w+)\s(\w+)$""".r

df.map{row =>
  row.getString(0) match {
    case log4RegExpr(me, cf, tf, tc, pn, pv) => LogItem(me, cf, tf, tc, pn, pv)
    case log1RegExpr(me, cf, tf, pn, pv) => LogItem(me, cf, tf, null, pn, pv)
    case log3RegExpr(me, cf, pn, pv) => LogItem(me, cf, null, null, pn, pv)
    case log2RegExpr(me, pn, pv) => LogItem(me, null, null, null, pn, pv)
    case _ => throw new Exception("Invalid format")
  }
}.show(false)

И вывод:

+--------------+-----------+---------------+--------------+--------------------------+----------+
|managedElement|cellFDD    |targetFrequency|targetCell    |paramName                 |paramValue|
+--------------+-----------+---------------+--------------+--------------------------+----------+
|LNJ05025D     |DNJ05025D31|AWS_2087       |null          |threshXHighQ              |0         |
|LNJ05024D     |BNJ05024D31|5035           |null          |connectedModeMobilityPrio |7         |
|LNJ05193B     |null       |null           |null          |dlMaxRetxThreshold        |8         |
|LNJ05024D     |DNJ05024D31|null           |null          |enableServiceSpecificHARQ |false     |
|LNJ05024D     |LNJ05024D31|null           |null          |primaryUpperLayerInd      |OFF       |
|LNJ05147D     |LNJ05147D11|2250           |310260-51992-1|cellIndividualOffsetEUtran|0         |
+--------------+-----------+---------------+--------------+--------------------------+----------+

Как видите, мы возвращаем экземпляр класса Case LogItem после сопоставления с одним из заданных выражений.

Здесь следует обратить внимание на две вещи:

  1. Вы должны быть Осторожно придерживаться порядка совпадений, как указано выше, от большего (больше совпадений для извлечения) до меньшего (меньше совпадений), в противном случае log4 может попасть в категорию log2, так как совпадение все еще существует!

  2. Из ваших примеров кажется, что EUtranCellRelation содержит специальные символы, поэтому вместо \w требуется \S+ (без пробела).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...