正则表达式:如何在复合表达式中获得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中打印为未定义。第二个表达式在每个标签之后产生<和</。我不明白这一点,更不用说如何在此问题的前面将更完整的表达式转换为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> 


慕妹3146593
浏览 183回答 3
3回答

慕田峪7331174

好的,让我们从thingy开始。很好,但从技术上讲,无需在单个括号中加上一个符号[5]&nbsp;[1-9]&nbsp;|&nbsp;[1-4][0-9]&nbsp;|&nbsp;5[0-7](为清楚起见,请在此处和下方使用空格)。对于第一部分,使用a | ab时,像这样的更改读起来更好ab?,即“ a,然后可选地是b`”。这给了我们&nbsp;<&nbsp;\/&nbsp;?现在,您要查找的“ and”(或“ and then”)运算符在正则表达式语言中非常简单-没什么。也就是说,a and then b就是ab。但是,如果我们像这样简单地将两个部分组合在一起a&nbsp;&nbsp;x&nbsp;|&nbsp;y&nbsp;|&nbsp;z这将是一个错误,因为|优先级较低,因此应解释为ax&nbsp;|&nbsp;y&nbsp;|&nbsp;z这不是我们想要的。因此,我们需要将数字事物放入parens中,由于下面将要解释的原因,这些parens也必须是不可捕获的:<\/?&nbsp;&nbsp;(?:&nbsp;[1-9]&nbsp;|&nbsp;[1-4][0-9]&nbsp;|&nbsp;5[0-7]&nbsp;)这与我们的定界符匹配,但是我们还需要介于两者之间的所有内容,因此我们将继续进行split输入。split通常返回与分隔符不匹配的字符串数组:"a,b,c".split(/,/)&nbsp;=>&nbsp;a&nbsp;b&nbsp;c如果我们也想包含定界符,则必须将其放置在捕获组中:"a,b,c".split(/(,)/)&nbsp;=>&nbsp;a&nbsp;,&nbsp;b&nbsp;,&nbsp;c因此,我们必须再次将所有内容包装在括号中:(&nbsp;&nbsp;<\/?&nbsp;&nbsp;(?:&nbsp;[1-9]&nbsp;|&nbsp;[1-4][0-9]&nbsp;|&nbsp;5[0-7]&nbsp;)&nbsp;&nbsp;)这就是原因?:-我们希望捕获全部内容,而不是数量部分。将所有内容放在一起似乎可以解决问题:s&nbsp;=&nbsp;"This&nbsp;is&nbsp;a<21>test</21>."&nbsp;&nbsp;&nbsp; console.log(s.split(/(<\/?(?:[1-9]|[1-4][0-9]|5[0-7])>)/))

慕田峪4524236

你差不多了。这真的很简单,就像用连接替换'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])>)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript