【问题标题】:RegEx for matching specific attributes and values用于匹配特定属性和值的正则表达式
【发布时间】:2019-09-25 14:06:16
【问题描述】:

我正在尝试删除一个不包含所有无用信息的巨大 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" + "(.*)" + "/>"));

  }

但这只会获取第一个变量。并且会包含一些无用的信息,比如 /> 结尾部分。

【问题讨论】:

标签: javascript regex regex-lookarounds regex-group regex-greedy


【解决方案1】:

从技术上讲,您可以通过DOMParser 将字符串转换为 XML 并以这种方式循环。您将需要一些 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"));
}

【讨论】:

    【解决方案2】:

    This expression 可能会帮助您这样做:

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

    为了安全起见,我添加了几个边界。如果你愿意,你可以减少这些界限。我还添加了几个捕获组,以便于调用。

    图表

    此图显示了表达式的工作原理:

    边界

    减少边界的一种方法是删除名称值,类似于this expression

    ^(Name=")([A-Za-z\s\x22_]+)(\s+Value="[A-Za-z0-9-:\s]+")([\/>\s]+)(.*)$
    

    图表

    性能

    此 JavaScript sn-p 在您的一个输入上使用简单的 100 万次 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. ? ");

    【讨论】:

      【解决方案3】:

      建议先使用xml解析器,然后删除您想要的字段,然后再次保存xml。我不建议使用文本字符串搜索来删除 XML 字段,因为 xml 是结构化数据,应该使用正确的工具来完成正确的工作。

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

      【讨论】:

        【解决方案4】:

        我认为它必须有效:

        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)

        我不知道您将如何使用这些数据,但您可能会发现一个由对象表示的模型很有用,其中属性“name”是键,属性“values”是值的数组(我重复了字符串共享并更改重复值以获得更好的示例):

        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)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-18
          • 1970-01-01
          • 2019-10-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多