regex 正则表达式匹配具有相同分隔符的 Package 短语(在许多中)

kfgdxczn  于 2023-08-08  发布在  其他
关注(0)|答案(4)|浏览(125)

我需要从一个HTML语料库(包含许多不同的HTML条目与许多不同的风格属性)解析的风格属性。
HTML的示例可以如下:

<span style="font-size:0.58em;font-family:'Times New Roman';">
<span style='font-size:0.58em;font-family:"Times New Roman";'>

字符串
因此,样式属性内容是单引号(')或双引号(“)之间的一些文本。如果文本开始在单引号之间换行,则应重新读取,直到满足结束单引号。如果以双引号开始,则应继续,直到满足结束双引号。
我生成了下面的正则表达式,它工作得很好:

/style\s*=\s*(?:'|").+?(?:'|")/gmi


问题是,我的解决方案无法检查开盘价和收盘价之间的一致性,因此它将产生如下解决方案:

style="font-size:0.58em;font-family:'Times New Roman'  --missing--> ;"
style='font-size:0.58em;font-family:"Times New Roman"  --missing--> ;'


有没有一种解决方案可以用一个正则表达式来检查这两种情况,或者唯一的选择是将当前正则表达式拆分为两个正则表达式来检查单引号或双引号?

5lhxktic

5lhxktic1#

不使用正则表达式,而是将html Package 到临时div中并从中读取样式可能是一个想法。例如:

const elemStrings = `<span style="font-size:0.58em;font-family:'Times New Roman';">
<span style='font-size:0.58em;font-family:"Times New Roman";'>`;
const elems = Object.assign(document.createElement(`div`), {innerHTML: elemStrings});
const styles = [...elems.querySelectorAll(`span`)].map(elem => 
  `style="${elem.style.cssText}"`);
console.log(styles);

字符串

lb3vh1jj

lb3vh1jj2#

从我上面的评论…

const markup = `
  <span style="font-size:0.58em;font-family:'Times New Roman';">foo</span>
  <span style='font-size:0.58em;font-family:"Times New Roman";'>bar</span>
`;
const regXStyleAttr = /style\s*=\s*(["']).*?\1/gi;

console.log(
  'regex based ... markup.match(regXStyleAttr) ...',
  markup.match(regXStyleAttr)
);

个字符

  • "...但更可靠的方法是使用DOMParser和parseFromString”*
const markup = `
  <span style="font-size:0.58em;font-family:'Times New Roman';">foo</span>
  <span style='font-size:0.58em;font-family:"Times New Roman";'>bar</span>
`;
console.log(
  'dom parser based ... and element node mapping ...',
  Array
    .from(
      new DOMParser()
        .parseFromString(markup, "text/html")
        .body
        .getElementsByTagName('*')
    )
    .map(elmNode => `style="${ elmNode.style.cssText }"`)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

的字符串

编辑...根据以下评论……

  • "...它是tollerant作为浏览器将是?它的性能是否与regex相当或更好?并且在stirng上使用任何解析都可以在不影响页面的情况下完成?“* - Skary

答案:是的-很可能-显然。

const markup_1 = `
  <span style="font-size:0.58em;font-family:'Times New Roman';">foo</span>
  <span style='font-size:0.58em;font-family:"Times New Roman";'>bar</span>
`;
const markup_2 = `
  <span style=font-size:0.58em;font-family:'Times New Roman'>foo</span>
  <span style=font-size:0.58em;font-family:"Times New Roman">bar</span>
`;
const markup_3 = `
  <span style=font-size:0.58em;font-family:'Times New Roman'>foo
  <span style=font-size:0.58em;font-family:"Times New Roman">bar
`;
console.log(
  'valid markup ...',
  Array
    .from(
      new DOMParser()
        .parseFromString(markup_1, "text/html")
        .body
        .getElementsByTagName('*')
    )
    .map(elmNode => `style="${ elmNode.style.cssText }"`)
);
console.log(
  'invalid markup ...',
  Array
    .from(
      new DOMParser()
        .parseFromString(markup_2, "text/html")
        .body
        .getElementsByTagName('*')
    )
    .map(elmNode => `style="${ elmNode.style.cssText }"`)
);
console.log(
  'even more broken markup ...',
  Array
    .from(
      new DOMParser()
        .parseFromString(markup_3, "text/html")
        .body
        .getElementsByTagName('*')
    )
    .map(elmNode => `style="${ elmNode.style.cssText }"`)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

的字符串

fxnxkyjh

fxnxkyjh3#

你可以使用前一场比赛来做。
https://regex101.com/
通常称为backreference,它将匹配由指定的捕获组#(编号)匹配和捕获的文本的重复。
为了减少歧义,也可以使用\g#或\g{#},其中#是一个数字。/(.)\1/

style\s*=\s*('|")(.+?)\1

字符串
你有没有想过使用像这样的HTML DOM解析器node-html-parser

bybem2ql

bybem2ql4#

你可以使用反向引用来解决它。
Regex:

style\s*=\s*(["'])(.*)\1

字符串
检查this结果。

相关问题