首页 > 解决方案 > 正则表达式:如何在复合表达式中获得 AND THEN 运算符的效果?

问题描述

我正在努力使用正则表达式。我想我理解个别的表达,但将一些东西组合在一起让我完全难过。我没有掌握使用与 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 中打印为未定义。第二个表达式在每个标签之后产生<和。</我不明白这一点,更不用说如何将这个问题前面的更完整的表达式转换为正则表达式。

所需的输出是:

'This is a', '<21>', 'test', '<\/21>', '.'

谢谢你。

补充 在收到 Georg 对这个问题的回答后,我开始对寻找一种逃避这些标签的方法感兴趣,特别是因为目前除了 Chrome 之外不支持负回溯。我的意思是\<21>将被视为常规文本,并且不会在该点生成字符串的拆分。如果你对类似的东西感兴趣,你可能会发现 Revo在这里提供的我的后续问题的答案很有帮助。

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> 

标签: javascriptregex

解决方案


你几乎明白了。这真的就像用连接替换“或”|和用and连接替换一样简单。?:然后通过添加到每个组的开头来确保您的组不匹配:

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

splitMDN 对和 regex的交互有解释。但简短的示例解释是:

'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])>)


推荐阅读