RegEx для сопоставления определенных атрибутов и значений - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь удалить огромный XML-файл, не содержащий всей ненужной информации. Файл будет выглядеть примерно так:

App_Data App="MOD" Name="Genre" Value="Series"/><App_Data App="MOD" 
Name="Show_Type" Value="Series"/><App_Data App="MOD" Name="Billing_ID" 
Value="10092"/><App_Data App="MOD" Name="Licensing_Window_Start" 
Value="2019-05-07 00:00:00"/><App_Data App="MOD" 
Name="Licensing_Window_End" Value="2019-05-13 23:59:59"/><App_Data 
App="MOD" Name="Preview_Period" Value="0"/><App_Data App="MOD" 
Name="Display_As_New" Value="4"/><App_Data App="MOD" 
Name="Display_As_Last_Chance" Value="7"/><App_Data App="MOD" 
Name="Provider_QA_Contact" Value="NBC Universal"/><App_Data App="MOD" 
Name="Suggested_Price" Value="0.00"/><App_Data App="MOD" 

Мне нужно будет найти значения для Show_Type, Licensing_Window_end, and Display_as_New

Итак, как мне превратить мою строку вывода в нечто вроде этого:

Name="Show_Type" Value="Series"
Name="Licensing_Window_End" Value="2019-05-13 23:59:59"
Name="Display_As_New" Value="4"

В настоящее время у меня есть что-то вроде этого:

  stripText(text) {
      return text.match(new RegExp("Show_Type" + "(.*)" + "/>"));

  }

Но это только первая переменная. и будет содержать некоторую бесполезную информацию, такую ​​как /> конечная часть.

Ответы [ 4 ]

0 голосов
/ 09 мая 2019

Я думаю, что это должно работать:

const text = `App_Data App="MOD" Name="Genre" Value="Series"/><App_Data App="MOD" 
Name="Show_Type" Value="Series fasfdasdf"/><App_Data App="MOD" Name="Billing_ID" 
Value="10092"/><App_Data App="MOD" Name="Licensing_Window_Start" 
Value="2019-05-07 00:00:00"/><App_Data App="MOD" 
Name="Licensing_Window_End" Value="2019-05-13 23:59:59"/><App_Data 
App="MOD" Name="Preview_Period" Value="0"/><App_Data App="MOD" 
Name="Display_As_New" Value="4"/><App_Data App="MOD" 
Name="Display_As_Last_Chance" Value="7"/><App_Data App="MOD" 
Name="Provider_QA_Contact" Value="NBC Universal"/><App_Data App="MOD" 
Name="Suggested_Price" Value="0.00"/><App_Data App="MOD"`

const result = text.match(/[Nn]ame\="(Show_Type|Licensing_Window_End|Display_As_New)"\s+[Vv]alue\="[^"]*"/g)

console.log(result)

enter image description here

Я не знаю, как вы будете использовать эти данные, но, вероятно, вам будет полезна модель, представленная объектом, где свойство "name" является ключом, а свойство "values" является массивом значений (я дублирую строка поделилась и изменила повторяющиеся значения, чтобы получить лучший пример):

enter image description here

const text = `App_Data App="MOD" Name="Genre" Value="Series"/><App_Data App="MOD" 
Name="Show_Type" Value="Series"/><App_Data App="MOD" Name="Billing_ID" 
Value="10092"/><App_Data App="MOD" Name="Licensing_Window_Start" 
Value="2019-05-07 00:00:00"/><App_Data App="MOD" 
Name="Licensing_Window_End" Value="2019-05-13 23:59:59"/><App_Data 
App="MOD" Name="Preview_Period" Value="0"/><App_Data App="MOD" 
Name="Display_As_New" Value="4"/><App_Data App="MOD" 
Name="Display_As_Last_Chance" Value="7"/><App_Data App="MOD" 
Name="Provider_QA_Contact" Value="NBC Universal"/><App_Data App="MOD" 
Name="Suggested_Price" Value="0.00"/><App_Data App="MOD"
App_Data App="MOD" Name="Genre" Value="Series"/><App_Data App="MOD" 
Name="Show_Type" Value="Series 2"/><App_Data App="MOD" Name="Billing_ID" 
Value="10092"/><App_Data App="MOD" Name="Licensing_Window_Start" 
Value="2019-05-07 00:00:00"/><App_Data App="MOD" 
Name="Licensing_Window_End" Value="2020-05-13 00:59:59"/><App_Data 
App="MOD" Name="Preview_Period" Value="0"/><App_Data App="MOD" 
Name="Display_As_New" Value="15"/><App_Data App="MOD" 
Name="Display_As_Last_Chance" Value="7"/><App_Data App="MOD" 
Name="Provider_QA_Contact" Value="NBC Universal"/><App_Data App="MOD" 
Name="Suggested_Price" Value="0.00"/><App_Data App="MOD" 
`

const result = text.match(/[Nn]ame\="(Show_Type|Licensing_Window_End|Display_As_New)"\s+[Vv]alue\="[^"]*"/g)

const objectResult = {
  show_type: [],
  licensing_window_end: [],
  display_as_new: [],
}

result.forEach((e)=>{
  const nameAndValue = e.match(/[Nn]ame\="(Show_Type|Licensing_Window_End|Display_As_New)"\s+[Vv]alue\="([^"]*)"/)
  switch (nameAndValue[1]) {
    case "Show_Type":
      objectResult.show_type.push(nameAndValue[2])
      break;
    case "Licensing_Window_End":
      objectResult.licensing_window_end.push(nameAndValue[2])
      break;
    case "Display_As_New":
      objectResult.display_as_new.push(nameAndValue[2])
      break;
    default:
      break;
  }
})

console.log(objectResult)
0 голосов
/ 08 мая 2019

Это выражение может помочь вам сделать это:

^(Name=")(Show_Type"|Licensing_Window_End"|Display_As_New")(\s+Value="[A-Za-z0-9-:\s]+")([\/>\s]+)(.*)$

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

enter image description here

Graph

Этот график показывает, как будет работать выражение:

enter image description here

1022 * Граница * Одним из способов уменьшения границы может быть удаление значений имени, аналогично этому выражению : ^(Name=")([A-Za-z\s\x22_]+)(\s+Value="[A-Za-z0-9-:\s]+")([\/>\s]+)(.*)$ enter image description here Graph

enter image description here

Performance

Этот фрагмент JavaScript показывает производительность этого выражения, используя простой цикл for на одном из ваших входов в миллион раз, вы можете просто выполнить замену строки на ваших входах, используя $1$2$3.

    repeat = 1000000;
    start = Date.now();
    
    for (var i = repeat; i >= 0; i--) {
    	var string = 'Name="Licensing_Window_End" Value="2019-05-13 23:59:59"/><App_Data';
    	var regex = /^(Name=")(Show_Type"|Licensing_Window_End"|Display_As_New")(\s+Value="[A-Za-z0-9-:\s]+")([\/>\s]+)(.*)$/g;
    	var match = string.replace(regex, "$1$2$3");
    }
    
    end = Date.now() - start;
    console.log("YAAAY! \"" + match + "\" is a match ??? ");
    console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");
0 голосов
/ 08 мая 2019

предлагает сначала использовать анализатор xml, затем удалить нужные поля, а затем снова сохранить xml. Я НЕ рекомендовал бы удалять поля XML с помощью поиска по текстовой строке, поскольку xml - это структурированные данные, для правильной работы следует использовать правильный инструмент.

https://www.w3schools.com/xml/xml_parser.asp

0 голосов
/ 08 мая 2019

Технически вы можете преобразовать строку в XML с помощью DOMParser и перебрать ее таким образом. Вам понадобится несколько операторов if для правильных атрибутов.

str = '<main><App_Data App="MOD" Name="Genre" Value="Series"/><App_Data App="MOD" Name="Show_Type" Value="Series"/><App_Data App="MOD" Name="Billing_ID" Value="10092"/><App_Data App="MOD" Name="Licensing_Window_Start" Value="2019-05-07 00:00:00"/><App_Data App="MOD" Name="Licensing_Window_End" Value="2019-05-13 23:59:59"/><App_Data App="MOD" Name="Preview_Period" Value="0"/><App_Data App="MOD" Name="Display_As_New" Value="4"/><App_Data App="MOD" Name="Display_As_Last_Chance" Value="7"/><App_Data App="MOD" Name="Provider_QA_Contact" Value="NBC Universal"/><App_Data App="MOD" Name="Suggested_Price" Value="0.00"/></main>';

let parser = new DOMParser();
let xmlDoc = parser.parseFromString(str, "text/xml");
let rows = xmlDoc.getElementsByTagName("App_Data");

for(z=0;z<rows.length;z++){
  console.log(rows[z].getAttribute("Name"),rows[z].getAttribute("Value"));
}
...