【问题标题】:Regex - ignoring text between quotes / HTML(5) attribute filtering正则表达式 - 忽略引号之间的文本 / HTML(5) 属性过滤
【发布时间】:2017-01-05 14:44:32
【问题描述】:

所以我有这个Regular expression,它基本上必须将给定的字符串过滤为 HTML(5) 格式 属性列表。它目前并没有让我感到充实,但这即将改变! (希望如此)

我试图实现,只要找到一个匹配项,它就会选择文本,直到下一次出现字符串的结尾,作为 second 匹配。所以如果你看一下当前的正则表达式:

/([a-zA-Z]+|[a-zA-Z]+-[a-zA-Z0-9]+)=["']/g

这样的字符串:hey="hey world" hey-heyhhhhh3123="Hello world" data-goed="hey"

将像这样被过滤/匹配:

MATCH 1. [0-3]   `hey`
MATCH 2. [16-32] `hey-heyhhhhh3123`
MATCH 3. [47-56] `data-goed`

这必须被视为 attribute-name(s),现在.. 我们只需要获取属性的 value(s)。所以提到的字符串必须有这样的结果:

MATCH 1. 
         1 [0-3]     `hey`
         2 [6-14]    `hey world`
MATCH 2. 
         1 [16-32]   `hey-heyhhhhh3123`
         2 [35-45]   `Hello world`
MATCH 3. 
         1 [47-56]   `data-goed`
         2 [59-61]   `hey`

任何人都可以尝试帮助我实现我的成就吗?它会很受欢迎!

【问题讨论】:

  • 我认为这里最好的模式是/([^\s=]+)=(?:"([^"]+)"|(\S+))/g
  • @WiktorStribiżew 我正在尝试转义引号中的引号/第一次出现和下一次出现之间的所有内容(对于内联的 javascript 执行/函数)。所以我不能使用你的正则表达式:/
  • @WiktorStribiżew 没错!介意将其发布为带有正则表达式解释的答案吗?这将是公认的答案!
  • @Bilal075_ 您是否有理由需要自己解析 HTML?浏览器已经很好地做到了,您可以通过 DOM 访问元素 attributes

标签: javascript regex filter attributes expression


【解决方案1】:

你可以使用

/([^\s=]+)=(?:"([^"\\]*(?:\\.[^"\\]*)*)"|(\S+))/g

regex demo

模式详情

  • ([^\s=]+) - 第 1 组捕获 1 个或多个字符,而不是空格和 = 符号
  • = - 等号
  • (?:"([^"\\]*(?:\\.[^"\\]*)*)"|(\S+)) - 2 个备选方案的非捕获组(可以添加一个更多 '([^'\\]*(?:\\.[^'\\]*)*)' 备选方案以说明单引号字符串文字)
    • "([^"\\]*(?:\\.[^"\\]*)*)" - 双引号字符串文字模式:
      • " - 双引号
      • ([^"\\]*(?:\\.[^"\\]*)*) - 第 2 组捕获除 \" 之外的 0+ 个字符,然后是 0+ 个任何转义符号序列,然后是除 \" 之外的 0+ 个字符
      • " - 一个结束的 dlouble 报价
    • | - 或
    • (\S+) - 第 3 组捕获一个或多个非空白字符

JS 演示(不支持单引号):

var re = /([^\s=]+)=(?:"([^"\\]*(?:\\.[^"\\]*)*)"|(\S+))/g; 
var str = 'hey="hey world" hey-heyhhhhh3123="Hello \\"world\\"" data-goed="hey" more=here';
var res = [];
while ((m = re.exec(str)) !== null) {
    if (m[3]) {
      res.push([m[1], m[3]]);
    } else {
      res.push([m[1], m[2]]);
    }
}
console.log(res);

JS 演示(支持单引号文字)

var re = /([^\s=]+)=(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|(\S+))/g; 
var str = 'pseudoprefix-before=\'hey1"\' data-hey="hey\'hey" more=data and="more \\"here\\""';
var res = [];
while ((m = re.exec(str)) !== null) {
  if (m[2]) {
    res.push([m[1], m[2]])
  } else if (m[3]) {
    res.push([m[1], m[3]])
  } else if (m[4]) {
    res.push([m[1], m[4]])
  }
}
console.log(res);

【讨论】:

  • 感谢您的清晰解释!但是.. 是否可以忽略值字段中的 EVERYTHING ?看看这个例子:regex101.com/r/tP1aY6/1。注意引号的公差(使用粗引号时,单引号必须转义,反之,使用单引号时,必须转义双引号)。
  • 我为这 3 个场景提供了一个正则表达式。它应该是一个单独的交替分支。我将添加一个sn-p。见regex101.com/r/tP1aY6/2。答案已更新。
  • 谢谢!这正是我所需要的。现在它只是一些意外匹配的阻碍(接收几个未定义值的键)。但我不能感谢你的时间!
  • 除了发表此评论外,我没有其他方式可以联系您。替代品(如果未使用)是否返回未定义?因为这似乎发生在您发布的最后一个 sn-p 中。我读过一些关于捕获子模式的内容。但是这个正则表达式不是这样的,是吗?
  • 当然,这就是为什么我发布我的 sn-p 来向您展示如何检查组是否匹配,并在此基础上构建输出数组/列表/whatver。
猜你喜欢
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 2022-07-29
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 2011-10-01
  • 2011-08-07
相关资源
最近更新 更多