我试图匹配域example.com,我想删除它下面的所有IP
输入:
[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
[example.net]
10.100.251.22
10.100.251.33
期望的输出:
[example.net]
10.100.251.22
10.100.251.33
这是我到目前为止所尝试的内容:
\[example.com\](\s+^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$)*
它有效,但不确定这是否有效。
我正在使用rubular进行正则表达式测试是一个示例
答案 0 :(得分:1)
我不会为复杂的正则表达式而烦恼,我会使用Ruby slice_before
来做这件事:
data = '[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
[example.net]
10.100.251.22
10.100.251.33
'
data.lines.slice_before(/\A\[/).select { |ary| ary.first[/example\.net/] }.join
# => "[example.net]\n10.100.251.22\n10.100.251.33\n"
打破它:
data
.lines # => ["[example.com]\n", "10.100.251.1\n", "10.100.251.2\n", "10.100.251.3\n", "[example.net]\n", "10.100.251.22\n", "10.100.251.33\n"]
.slice_before(/\A\[/) # => #<Enumerator: #<Enumerator::Generator:0x007f987b8b4528>:each>
.select { |ary| ary.first[/example\.net/] } # => [["[example.net]\n", "10.100.251.22\n", "10.100.251.33\n"]]
.join # => "[example.net]\n10.100.251.22\n10.100.251.33\n"
正则表达式很棒,我会在必要时使用它们,但它们并不总是最适合任务的工具。它们可能非常脆弱且非常危险,并且极大地增加了维护代码的任务,特别是当它们变得更复杂时。
这也可以使用触发器完成,但解释的是留下一个不同的问题:&#34; What is a flip-flop operator?&#34;。
答案 1 :(得分:0)
答案 2 :(得分:0)
我们得到了
str =<<-END
[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
[example.net]
10.100.251.22
10.100.251.33
END
#=> "[example.com]\n10.100.251.1\n10.100.251.2\n10.100.251.3\n[example.net]\n10.100..."
问题有点令人困惑,因为所谓的输出被认为是
[example.net]
10.100.251.22
10.100.251.33
但这也是要删除的内容。接下来的内容返回未删除的行,但更改它以返回已删除的位将是一件简单的事情。此外,问题还不清楚字符串"[example.net]"
是否已知,或者它只是"[example.com]"
“块”后面的示例。也不清楚是否有两个“块”,如示例中所示,或者可能有一个或两个以上的块。
如果您知道"[example.net]"
紧跟"[example.com]"
块之后,您可以写
r = /
\[example\.com\] # match string
.*? # match any number of characters, lazily
(?=\[example\.net\]) # match string in positive lookahead
/mx # multiline and free-spacing modes
puts str[r]
[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
如果您不知道"[example.com]"
“块”后面的内容,除了下一个块的第一行(如果有的话)包含至少一个字符或句点以外的字符,可以写
r = /
\[example\.com\]\n # match string
.*? # match any number of any characters, lazily
(?:[\d.]*\n) # match a string containing > 0 digits and periods,
# followed by a newline, in a non-capture group
+ # match the above non-capture group > 0 times
/x # free-spacing mode
puts str[r]
[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
答案 3 :(得分:0)
你的正则表达非常接近。您错过的是在正确的位置进行分组和换行构造:
/^\[example\.com\]\R*(?:(?:\d{1,3}\.){3}\d{1,3}\R*)*/
请参阅Rubular demo
<强>详情:
^
- 行首\[example\.com\]
- [example.com]
文字子字符串\R*
- 零个或多个换行符(对于较旧的Ruby版本,请使用(?:\r?\n|\r)*
)(?:(?:\d{1,3}\.){3}\d{1,3}\R*)*
- 零个或多个序列
(?:\d{1,3}\.){3}
- 3个1到3位数的序列和一个点\d{1,3}
- 1至3位数字\R*
- 0+换行str =<<DATA
[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
[example.net]
10.100.251.22
10.100.251.33
DATA
rx = /^\[example\.com\]\R*(?:(?:\d{1,3}\.){3}\d{1,3}\R*)*/
puts str[rx]
答案 4 :(得分:0)
处理数据的一种方法是将其视为INI文件。启用了multi-line option的正则表达式可以将INI文件的字符串表示形式分解为多个节的数组,如下所示:
ini = <<~'EOF'
[example.com]
10.100.251.1
10.100.251.2
10.100.251.3
[example.net]
10.100.251.22
10.100.251.33
EOF
# Scan for INI section headers.
sections = ini.scan /^\[.*?\]$[^\[]*/m
然后,您可以使用Enumerable#grep仅提取所需的部分。例如,要提取example.net
部分:
section_title = 'example.net'
sections.grep /\A\[#{Regexp.escape section_title}\]\s*$/
#=> ["[example.net]\n10.100.251.22\n10.100.251.33\n"]
[
,.
和]
等字符将无法满足您的预期。