我试图了解如何制作仅与某个模式匹配的正则表达式,如果该模式不包含在另一个模式中。
在下面的示例中,仅当破折号不在[code] [/ code]标记中时,我才想匹配它们。
---------
[code]
-------------------------------------------------------------------------------------
Some text
-----------------
Some other text
-------------------------------------------------------------------------------------
test
[/code]
我已经搜索了有关前行和后行的解释,但无法理解它是否以及如何适合我的需求。
我想同时使用负向后看和负向后看,但似乎无法在负向后看模式中使用+或*。
例如,这是行不通的(因为后面的负面表情中有+)
/(?<!\[code\].+?)(-{5,100})(?!.+?\[\/code\])/m
如何以其他方式实现这一目标?
答案 0 :(得分:2)
如果标签没有嵌套,则一种可能性是从开始标签到结束标签匹配,以匹配您不想要的标签。然后使用交替方式在一组中捕获您想要的内容,在这种情况下为5到100倍的连字符。
\[code\](?:(?!\[\/?code\]).)*\[\/code]|(-{5,100})/m
说明
\[code\]
匹配[code]
(?:
非捕获组
(?!\[\/?code\]).
断言[code]
后是否用可选的/
来代替右边的[
,然后匹配任何字符。)*
重复非捕获组并重复0次以上\[\/code]
匹配[/code]
|
或(-{5,100})
在第1组中捕获,匹配连字符5-100倍答案 1 :(得分:2)
我不认为正则表达式是此处工作的正确工具。
str = <<END
---------
[code]
-------------------------------------------------------------------------------
Some text
----------------------------------
Some other text
-------------------------------------------------------------------------------
test
[/code]
------------
---
[code]
Some text
-------------------------------------------
[/code]
------------
END
within = false
str.split("\n").select do |line|
case line
when "[code]"
within = true
false
when "[/code]"
within = false
false
else
within == false
end
end
#=> ["---------", "------------", "---", "------------"]
如果不推荐使用我喜欢的flip-flip operator,我会使用它。
str.split("\n").reject do |line|
true if line == "[code]"..line == "[/code]"
end
#=> ["---------", "------------", "---", "------------"]
Hold the phone!看起来Matz拥有un-deprecated it! (滚动到结束。)