regex 正则表达式匹配,仅当找到冒号时

hs1rzwqc  于 2023-03-04  发布在  其他
关注(0)|答案(5)|浏览(220)

我想写一个匹配端口的正则表达式。这很好用,但通常时间也会匹配。我想创建一个负的向前看和向后看,这样如果字符串中有另一个冒号,它就不会匹配。但我犯了一个错误,我无法发现它:

我希望端口匹配,但时间不匹配。

(?<!:):\d{1,5}\b(?!:)

这是link to the saved regex
有时候,有些端口显示为:443和:80,但没有IPv4信息。这就是为什么我正在研究环视解决方案。我使用的是ECMAScript。

tkclm6bt

tkclm6bt1#

如果你使用的是Javascript,并且你可以使用可变长度的lookbehind,你可以在左边Assert:,但是不能在左边Assert.,然后是数字和:

(?<=:)(?<!:\d+:)\d{1,5}\b(?!:)

Regex demo

const regex = /(?<=:)(?<!:\d+:)\d{1,5}\b(?!:)/g;
const s = `10.0.243.7:38518
62.11.21.68:443
01:11:22
21:15:19`;
console.log(s.match(regex));

如果您还想匹配冒号:

(?<!:\d+):\d{1,5}\b(?!:)

Regex demo

const regex = /(?<!:\d+):\d{1,5}\b(?!:)/g;
const s = `10.0.243.7:38518
62.11.21.68:443
01:11:22
21:15:19`;
console.log(s.match(regex));
cld4siwp

cld4siwp2#

此正则表达式:

乌尔

^\d+\.\d+\.\d+\.\d+:\K\d{1,5}


平方

^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}:\K\d{1,5}

假设ip's仅为ipv4
乌尔
平方英寸Online Demo

xghobddn

xghobddn3#

我想写一个匹配端口的正则表达式。我忘了提一下,端口有时显示时没有IP。
ECMAScript正则表达式:

^((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b)){4}|):(?<port>((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4})))$

PCRE:

^((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b)){4}|):\K((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$

这可以处理所有情况,包括显示的端口没有IP地址。
查看ECMAScriptPCRE的实际应用。

  • 首先Assert字符串的开头(^)。
  • 然后捕获0 - 9、10 - 99、100 - 199、200 - 249或250 - 255之间的数字。
  • 数字后需要一个句号,重复4次。
  • 字边界(\b)防止第四个匹配.:模式。
  • 然后,我们重置(\K)以忽略PCRE中匹配的IPv4地址,并使用ESMAScript中的命名捕获。
  • 然后,我们为端口匹配0 - 9、10 - 99、100 - 999、1000 - 9999、10000 - 59999、60000 - 64999、65000 - 65499、65500 - 65529、65530 - 65535。
  • 最后我们Assert结束($)。

示例Javascript:

const regex = /^((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b)){4}|):(?<port>((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4})))$/gm;

const input = `10.0.243.7:38518
62.11.21.68:443
01:11:22
21:15:19
10.20.30.40:2312
10.20..40:2312
10.20.40.:2312
10.20.40:5312
10.20.30.40:0
10.20.30.40:0;
:293
:65536
1.1.2.2:65536`;

for (const match of input.matchAll(regex)) {
    console.log(`${match.groups.port}`);
}
z31licg0

z31licg04#

如果您对行中单个:之后的任何内容感兴趣:

^[^:]*:(\d{1,5})$

并使用组1作为端口。
如果您希望限制性更强一些,将端口的范围限制为实际的0到65535,可以使用以下命令:

^[^:]*:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[0-5]?\d{1,4})$

(for“为了简洁;- )”我允许在这个正则表达式中使用前导零)

o2rvlv0m

o2rvlv0m5#

正如您提到的,Ecmascript提供了一个解决方案,可以单独匹配端口号,也可以将其作为IPv4的结尾部分:

const regex = /(?:\.\d+|\B)(?::)(\d{1,5})\b(?!:)/g;

// Alternative syntax using RegExp constructor
// const regex = new RegExp('(?:\\.\\d+|\\B)(?::)(\\d{1,5})\\b(?!:)', 'g')

const str = `10.0.243.7:38518    :440
62.11.21.68:443   port  :80
01:11:22
21:15:19
:443 `;
let m;

ports = Array.from(str.matchAll(regex), (m) => m[1])
console.log(ports)

相关问题