【问题标题】:How to make a regex to recognise a specific pattern of words如何制作正则表达式来识别特定的单词模式
【发布时间】:2025-12-19 09:35:10
【问题描述】:

我的正则表达式很差,但由于某种原因,我别无选择,只能使用它。

我正在尝试从网页表中提取“端口号”列表及其各自的“IP 地址”。而且由于它是一个动态网页,使用 AJAX 和 PHP 的东西来生成动态内容,因此所有的表格元素都没有任何 id 或 class 或任何独特的东西。我已经使用str_replace 消除了所有/t, /r and /n,整个内容只包含单词和空格。

这里是端口和ip地址的例子:

端口 - Fa0/0、Gi1/0/2.100、Ethernet01、GigaEther-01(包含大小写、点、破折号、斜线和数字,不能超过 16 个字符,不能有空格)

IP adrr - 123.123.123.123, 1.1.12.12, 123.12.1.1(与普通ip addr没有区别)

不过还好,所有的“端口”和“IP地址”后面都不是端口镜像就是ip镜像,比如

...<img border='0' src='images/port.png' width='18' heigh='18'>Fa0/0</td>... OR
...<img border='0' src='images/ip.png' width='18' heigh='18'>1.1.1.1</td>...

我相信 port/IP 和 img/td 标签之间没有空格。因此,我可以将其用作提取它们的模式,因此我使用了以下模式:

端口-

$pattern = "/<img border\='0' src='images\/port\.png' width\='18' height\='18'>([a-zA-Z0-9\/ _-]{1,15})<\/td>/";

IP地址-

$pattern = "<img border\='0' src\='images\/ip\.png' width\='18' height\='18'>\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b <\/td>/";

然后是 preg_match_all($pattern, $content, $matches); . . .

但是他们都没有返回给我,然后我尝试了以下模式:

端口-

$pattern = "/<img border\='0' src='images\/port\.png' width\='18' height\='18'>(.*)<\/td>/";

IP地址-

$pattern = "<img border\='0' src\='images\/ip\.png' width\='18' height\='18'>(.*)<\/td>/";

...

但是这些模式会返回类似的东西

<img border\='0' src='images\/port\.png' width\='18' height\='18'>Fa0/0
<\/td>....(Followed by a bunch of unwanted text and code)
......<\/td>

因为(.*) 会将&lt;img....&gt;&lt;/td&gt; 之间的任何内容视为有效匹配

而且,我只尝试了特定的 IP 地址正则表达式,$pattern = "/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/";

它只向我返回 IP 地址(如 111.22.3.119),但不幸的是,网页中的某些链接 url 也包含我不想要的 IP 地址。

然后我尝试了$pattern = "/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}&lt;\/td&gt;\b/";,它什么也没返回...

感谢任何愿意帮助我的人,谢谢。

* 编辑 1 *

我试过$pattern = "/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b&lt;\/td&gt;/";,它可以工作,不知道为什么,但仍在想办法解决端口正则表达式....

【问题讨论】:

  • 一个简单的想法:你可能会从([^&gt;]*) 获得比(.*) 更多的东西。正则表达式默认为“贪婪”,如果它让您跳过开始或结束标签,这可能会很糟糕。 (另外,你删除了所有的行尾吗?!!如果它们可用,就把它们放回去!!!或者甚至在某些标签结束后添加一些......)正则表达式是一个面向行的工具。
  • 如上所述,我的正则表达式真的很差,请问([^&gt;]* 是什么意思? “删除所有行尾”是什么意思?我确实删除了所有\n,因为有时我确实遇到过代码类似于&lt;img...&gt;Fa0/0(next line here)&lt;/td&gt;,这导致我的模式不起作用。感谢您能在这方面给我更多启发,谢谢!

标签: php regex ip-address port-number


【解决方案1】:
$pattern1 = '#<img[^>]+>([a-z][\w./-]{1,16})</td>#i';
$pattern2 = '#<img[^>]+>([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})</td>#';

【讨论】:

  • Pattern2 适合我!!但是对于 Pattern1,它将 pattern2 的输出与端口号混合在一起,当我尝试 $pattern = "#&lt;img id\='rmcode5' border\='0' src='images\/port\.png' width\='18' height\='18'&gt;([\w./-]{1,16})&lt;/td&gt;#"; 时,它只返回其中的一部分,但不是全部,无论如何,非常感谢您的帮助。
  • @user2619841 - 端口 ID 总是以字母开头,还是有其他方法可以区分两者?
  • @user2619841 - 我更改了 pattern1 假设它们以字母开头。如果不是这样,请告诉我。
  • 对不起,id\='rmcode5'实际上是我用编辑过的虚拟代码编写的,在真实的网页中它不存在。无论如何,您编辑的 pattern1 工作!非常感谢!!