反应组件中的正则表达式标记在两个可能的标签中的名称

问题描述 投票:2回答:3

我需要一个正则表达式找到<Field ...name="document"><FieldArray ...name="document">替换为空字符串。它们可以跨多行定义。

这不是html或xhtml,它只是一个包含<Field><FieldArray>的文本字符串

字段示例:

      <Field
        component={FormField}
        name="document"
        typeInput="selectAutocomplete"
      />

FieldArray的示例:

      <FieldArray
        component={FormField}
        typeInput="selectAutocomplete"
        name="document"
      />

它们位于组件列表中。例:

      <Field
        name="amount"
        component={FormField}
        label={t('form.amount')}
      />
      <Field
        name="datereception"
        component={FormField}
        label={t('form.datereception')}
      />
      <Field
        component={FormField}
        name="document"
        typeInput="selectAutocomplete"
      />
      <Field
        name="datedeferred"
        component={FormField}
        label={t('form.datedeferred')}
      />

我已经阅读了一些解决方案,比如在Extract image src from a string找到src但是他的结构与我正在寻找的不同。

javascript node.js regex
3个回答
2
投票

不建议使用parse [X]HTML with regex。如果你有可能使用domparser,我建议使用它而不是正则表达式。

如果没有其他方法,您可以使用此方法来查找和替换您的数据:

<Field(?:Array)?\b(?=[^\/>]+name="document")[^>]+\/>

说明

  • <Field与可选的“数组”匹配,并以单词边界<Field(?:Array)?\b结尾
  • 积极向前看(?=
  • 其中断言以下不是/>并遇到name =“document”[^\/>]+name="document"
  • 匹配不是>一次或多次[^>]+
  • 匹配\/>

var str = `<Field
    name="amount"
    component={FormField}
    label={t('form.amount')}
  />
  <Field
    name="datereception"
    component={FormField}
    label={t('form.datereception')}
  />
  <Field
    component={FormField}
    name="document"
    typeInput="selectAutocomplete"
  />
  <Field
    name="datedeferred"
    component={FormField}
    label={t('form.datedeferred')}
  />
<FieldArray
    component={FormField}
    typeInput="selectAutocomplete"
    name="document"
  /><FieldArray
    component={FormField}
    typeInput="selectAutocomplete"
    name="document"
  />` ;
str = str.replace(/<Field(?:Array)?\b(?=[^\/>]+name="document")[^>]+\/>/g, "");
console.log(str);

2
投票

这是实际XML解析的答案,没有正则表达式:

var xml = document.createElement("xml");
xml.innerHTML = `
      <Field
        name="amount"
        component={FormField}
        label={t('form.amount')}
      />
      <FieldDistractor
        component={FormField}
        name="document"
        typeInput="selectAutocomplete"
      />
      <Field
        name="datereception"
        component={FormField}
        label={t('form.datereception')}
      />
      <Field
        component={FormField}
        name="document"
        typeInput="selectAutocomplete"
      />
      <Field
        name="datedeferred"
        component={FormField}
        label={t('form.datedeferred')}
      />
      <FieldArray
        component={FormField}
        typeInput="selectAutocomplete"
        name="document"
      /><FieldArray
        component={FormField}
        typeInput="selectAutocomplete"
        name="document"
      />
`;

var match = xml.querySelectorAll(
  `field:not([name="document"]), fieldarray:not([name="document"]),
    :not(field):not(fieldarray)`
);
var answer = "";
for (var m=0, ml=match.length; m<ml; m++) {
  // cloning the node removes children, working around the DOM bug
  answer += match[m].cloneNode().outerHTML + "\n";
}
console.log(answer);

在写这个答案时,我在DOM解析器中发现了Firefox(Mozilla Core bug 1426224)和Chrome(Chromium bug 796305)中的一个错误,它不允许通过innerHTML创建空元素。我的original answer使用正则表达式对代码进行预处理和后处理以使其工作,但是在XML上使用正则表达式是如此令人讨厌,以后我将其更改为仅使用cloneNode()(使用隐式deep=false)剥离子代。

所以我们将XML转储到一个虚拟DOM元素(我们不需要放在任何地方),然后我们运行querySelectorAll()来匹配一些指定你的要求的CSS:

  • field:not([name="document"])“Field”元素缺乏name="document"属性,或
  • fieldarray:not([name="document"])“FieldArray”元素缺少该属性,或
  • :not(field):not(fieldarray)任何其他元素

0
投票

您可以使用正则表达式解析HTML标记,因为解析标记本身并不特别,并且首先将其解析为原子操作。

但是,你不能使用正则表达式来超越原子标记。 例如,您找不到平衡标签关闭以匹配open为 这会对正则表达式能力造成巨大压力。

Dom解析器的作用是使用正则表达式来解析标记,然后使用内部 算法创建树并执行处理指令来解释 并重新创建一个图像。 当然,正则表达式不会这样做。

坚持严格解析标签,包括不可见的内容(如脚本), 也不是那么容易。 内容可以隐藏或嵌入标签,当您查找它们时,您不应该这样做 找到他们。

所以,实质上,你必须解析整个html文件才能找到真实的 标记你的寻找。 有一个普通的正则表达式可以做到这一点,我不会在这里包括。 但如果你需要,请告诉我。

所以,如果你想直接跳入火中而不解析全部 整个文件的标签,这是要使用的正则表达式。

它本质上是解析所有标签的版本。 这个味道找到你需要的标签和任何attribute =值, 并且还发现它们无序。 它还可用于在同一标签内查找无序,多个attr / val。

这是为了您的用法:

/<Field(?:Array)?(?=(?:[^>"']|"[^"]*"|'[^']*')*?\sname\s*=\s*(?:(['"])\s*document\s*\1))\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]*?)+\/>/

解释/格式化

 < Field                # Field or  FieldArray  tag
 (?: Array )?

 (?=                    # Asserttion (a pseudo atomic group)
      (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
      \s name \s* = \s* 
      (?:
           ( ['"] )               # (1), Quote
           \s* document \s*       # With name = "document"
           \1 
      )
 )
 \s+ 
 (?: " [\S\s]*? " | ' [\S\s]*? ' | [^>]*? )+
 />

运行演示:https://regex101.com/r/ieEBj8/1

© www.soinside.com 2019 - 2024. All rights reserved.