Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 重复子序列的有效正则表达式_Regex - Fatal编程技术网

Regex 重复子序列的有效正则表达式

Regex 重复子序列的有效正则表达式,regex,Regex,我试图构造一个regexp,其中一个子序列预计会在整个匹配的不同场景中出现。一个类似的例子是I/P地址:对于输入字符串blah129.186.51.101blah,匹配为:129.186.51.101,但子序列129、186、51和101都满足匹配条件,即它们位于0和255之间(简化条件)。因此,我的正则表达式最终类似于: (?:{regexp for 0 to 255}\.){3}({regexp for 0 to 255}) 有没有一种更优雅的方法来处理这样的场景:regexp可以包含更小

我试图构造一个regexp,其中一个子序列预计会在整个匹配的不同场景中出现。一个类似的例子是I/P地址:对于输入字符串
blah129.186.51.101blah
,匹配为:
129.186.51.101
,但子序列129、186、51和101都满足匹配条件,即它们位于0和255之间(简化条件)。因此,我的正则表达式最终类似于:

(?:{regexp for 0 to 255}\.){3}({regexp for 0 to 255})

有没有一种更优雅的方法来处理这样的场景:regexp可以包含更小的regexp片段,这些片段可以在整个regexp中再次引用?

也许您可以尝试以下方法:

((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?!\d)\.??){4}

虽然在特殊情况下,如
blah129.186.51.1011blah
,这将失败,但我认为这应该是一个失败的匹配,因为它不是一个有效的ip?

另外,看看这个模式:(也能够匹配前导零)

编辑

我建议使用正则表达式,但我不会建议您使用正则表达式。您应该使用
SPLIT
函数迭代索引,并将其与0到255之间的范围进行比较。请参见顶部的我的评论


关于Regex,如果字符串中有IP地址,则可以分别使用
^
$
作为该模式的前缀和后缀。

这将解决您的问题:

((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?!\d)\.??){4}
锚固(见试验结果):

测试结果:

^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$
// Valid IP addresses
// 1.2.3.4
// 255.255.255.255

// Invalid IP addresses
// 1.2.3
// 1.2.3.
// .1.2.3
// 1.2.3.4.5.6.7.8 (use anchors ^ and $ to skip these if needed, since 1.2.3.4 and 5.6.7.8 will still be captured)
// 999.999.999.999 
// 299.299.299.299
// 001.002.003.004 (these use octal notation, not decimal)
锚定正则表达式不会在文本内部匹配,只有在您希望对只应包含IP的字符串进行非常严格的匹配时才会匹配

更新:


逻辑:
([0-255]\.{4})
用正则表达式以外的东西进行验证会更容易。@diEcho抱歉,您的表达式错了@Blender当然是,但问题是使用regexp。您有更有效的regexp吗?正确的方法是使用
拆分并检查
0这似乎有效(我将进行更多的测试),但您能否解释一下:(?!\d)\.??){4}部分是如何工作的?它似乎也承认11.1.1.1.11是“11.1.1.1”,那么为什么“1.1.1.11”是不可接受的呢?+1对于胆小鬼来说,提出非贪婪的
\。??
(注意
(?!\d)
反向前瞻是至关重要的)。@Neel
(?!\d)
意味着下一个字符不应该是一个数字(这个比较不会消耗字符),而
\.-
意味着
应该出现0或1次,但不要贪心,否则它将匹配
129.186.51.101.
blah129.186.51.101.blah
中。blah
包装成脚本:
while(){如果m/(?:(?:25[0-5]| 2[0-4][0-9]|[1-9][1-9];[1240-9])/。{
打印匹配的模式和原始数据,我发现Perl接受1.1.1.11、11.1.1.11、11.1.1.1.11,给出合理的预期结果(不包括终端
)。@leonhart再次说明:您的示例:blah129.186.51.1011blah至少应该将“129.186.51.101”解析为I/P的有效部分,对吗?我认为它在这里也不起作用。。。抱歉。前导插入符号和尾随美元阻止它与问题中的“blah”示例匹配。然而,移除这些是微不足道的。更严重的是,您的正则表达式将接受12918651101作为有效项(实际上,它将
1291
视为匹配项)。这在一定程度上是由于处理备选方案的方式产生了一个稍微奇怪的结果。你想要的是更长的备选方案,而不是更短的。@JonathanLeffler,它确实会匹配1291(在prev regex中),但我相信这不是因为对备选方案的处理很奇怪,而是因为它是
\。?
,还有
^
$
背后的意图,它被添加为只选择有效的IP以及有效的子序列。如果可能的话,每个人都喜欢较短的。好的,一个好球!thanks@Neel,如果仍然有问题,请看这个正则表达式。@如果你看到这个问题,请不要担心,我已经提到我有正确的正则表达式,但是请注意,这个正则表达式有两个相似的部分,一个用于前三个片段,另一个用于最后一个片段。我在寻找一个更紧凑的解决方案。我想你提到的链接(例如live)不是你想要附加的链接。它不包含任何文本。我的结果在regexbuddy中进行了测试,运行良好。我提供的链接只是额外的,我可以在表达式区域和测试数据区域用文本打开它:/hmm您的权利,在另一个浏览器中测试了它,文本消失了,更新了我的答案以使用您也使用的答案。您好。我已经向Debuggex推送了一个热修复程序来修复这个问题。上一个链接应该适用于所有主要浏览器。很抱歉给您带来不便。@SergiuToarca太棒了,我把链接改回了,debuggex做得很好,非常适合可视化调试:)
// Valid IP addresses
// 1.2.3.4
// 255.255.255.255

// Invalid IP addresses
// 1.2.3
// 1.2.3.
// .1.2.3
// 1.2.3.4.5.6.7.8 (use anchors ^ and $ to skip these if needed, since 1.2.3.4 and 5.6.7.8 will still be captured)
// 999.999.999.999 
// 299.299.299.299
// 001.002.003.004 (these use octal notation, not decimal)