为了账号安全,请及时绑定邮箱和手机立即绑定

正则表达式:如何在复合表达式中获得AND THEN运算符的作用?

正则表达式:如何在复合表达式中获得AND THEN运算符的作用?

慕妹3146593 2021-04-15 17:14:31
我正在努力使用正则表达式。我想我了解个人的表达方式,但将某些内容组合在一起完全使我感到困惑。我不了解如何使用与AND运算符等效的东西来将我想要的片段连接成一个“完整”的匹配表达式。例如,我想将一个字符串拆分为一个数组,以中断<1>to<57>和</1>to的任何值</57>。所以,我以为我需要这样的东西:( '<' or '<\/' ) and ( [1-9] or [1-4][0-9] or [5][0-7] ) and '>'我可以单独使用<[1-4] [0-9]>或</ [1-4] [0-9]>,但是当与'|'一起使用时 它返回部分匹配项或在完全匹配项之间未定义。你能告诉我我不明白的事吗?附件是我的例子。如果对第一个表达式单击“尝试”,它将在每个<21>或之后产生空值</21>。测试时,它在console.log中打印为未定义。第二个表达式在每个标签之后产生<和</。我不明白这一点,更不用说如何在此问题的前面将更完整的表达式转换为regExp了。所需的输出是:'This is a', '<21>', 'test', '<\/21>', '.'谢谢你。补充 在收到Georg对这个问题的回答后,我开始对转义这些标签的方法感兴趣,特别是因为当前仅在Chrome中不支持负向回溯。通过这种方式,我的意思是\<21>将被视为常规文本,并且此时不会生成字符串拆分。如果你有兴趣在类似的东西,你可能会找到答案由雷沃提供我的后续问题在这里非常有用。let b, B = document.querySelectorAll('button');for ( b of B ) b.addEventListener( 'click', split_str, false );function split_str( evt ) {   let e = evt.currentTarget,       r = new RegExp( e.previousElementSibling.value ),       s = e.parentNode.previousElementSibling.value;   e.parentNode.lastElementChild.textContent = s.split(r);    }div > div  { border: 1px solid rgb(150,150,150); width: 500px; height: 200px;padding: 5px; }input { border: 1px solid rgb(150,150,150); width: 500px; margin-bottom: 20px; padding:5px; }<input type='text' value="This is a<21>test</21>."><div><input type='text' value="(<[1-4][0-9]>)|(<\/[1-4][0-9]>)"> <button>try</button><input type='text' value="((<|<\/)[1-4][0-9]>)"> <button>try</button><div></div></div> 
查看完整描述

3 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

好的,让我们从thingy开始。很好,但从技术上讲,无需在单个括号中加上一个符号[5]

 [1-9] | [1-4][0-9] | 5[0-7]

(为清楚起见,请在此处和下方使用空格)。

对于第一部分,使用a | ab时,像这样的更改读起来更好ab?,即“ a,然后可选地是b`”。这给了我们

 < \/ ?

现在,您要查找的“ and”(或“ and then”)运算符在正则表达式语言中非常简单-没什么。也就是说,a and then b就是ab

但是,如果我们像这样简单地将两个部分组合在一起

a  x | y | z

这将是一个错误,因为|优先级较低,因此应解释为

ax | y | z

这不是我们想要的。因此,我们需要将数字事物放入parens中,由于下面将要解释的原因,这些parens也必须是不可捕获的:

<\/?  (?: [1-9] | [1-4][0-9] | 5[0-7] )

这与我们的定界符匹配,但是我们还需要介于两者之间的所有内容,因此我们将继续进行split输入。split通常返回与分隔符不匹配的字符串数组:

"a,b,c".split(/,/) => a b c

如果我们也想包含定界符,则必须将其放置在捕获组中:

"a,b,c".split(/(,)/) => a , b , c

因此,我们必须再次将所有内容包装在括号中:

(  <\/?  (?: [1-9] | [1-4][0-9] | 5[0-7] )  )

这就是原因?:-我们希望捕获全部内容,而不是数量部分。

将所有内容放在一起似乎可以解决问题:


s = "This is a<21>test</21>."   
console.log(s.split(/(<\/?(?:[1-9]|[1-4][0-9]|5[0-7])>)/))


查看完整回答
反对 回复 2021-04-29
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞


你差不多了。这真的很简单,就像用连接替换'or'或用串联|替换一样and。然后,通过?:在每个组的开头添加以下内容,确保您的组不匹配:


(?:<|<\/)(?:[1-9]|[1-4][0-9]|[5][0-7])>


MDN对split和正则表达式的交互进行了解释。但是,简短的示例解释是:


'hi_joe'.split('_'); // ['hi', 'joe']

'hi_joe'.split(/_/); // ['hi', 'joe']

'hi_joe'.split(/(_)/); // ['hi', '_', 'joe']

'hi_joe'.split(/(?:_)/); // ['hi', 'joe']

根据评论更新,如果您还希望在结果数组中使用<##>,则将正则表达式包装在另一组括号中。


((?:<|<\/)(?:[1-9]|[1-4][0-9]|[5][0-7])>)


查看完整回答
反对 回复 2021-04-29
  • 3 回答
  • 0 关注
  • 182 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信