IP 正则表达式验证

1 投票
2 回答
2907 浏览
提问于 2025-04-17 06:33

我一直在尝试验证一个输入的字符串(在这个例子中是sys argv[1])。我需要创建一个脚本,去读取一个日志文件,并匹配源IP和目标IP与脚本输入的任何参数。有效的输入类型有:

  • 一个完整的IP地址或部分IP地址
  • "any"(这个字符串表示某一列中的所有IP地址)。

到目前为止,我有以下代码。每当我在bash中运行这个脚本并传入一个参数(比如随便一个数字或单词/字母等)时,我都会遇到错误。请告诉我如何解决这些问题。非常感谢能有一种方法来验证输入是否符合IP地址的正则表达式和单词any。

#!/usr/bin/python

import sys,re

def ipcheck(ip):
    #raw patterns for "any" and "IP":
    ippattern = '([1-2]?[0-9]?[0-9]\.){1,3}([1-2]?[0-9]?[0-9])?'
    anypattern = any
    #Compiled patterns
    cippattern = re.compile(ippattern)
    canypattern = re.compile(any)
    #creating global variables for call outside function    
    global matchip
    global matchany
    #matching the compiled pattern 
    matchip = cippattern.match(ip)
    matchany = canypattern.match(ip)

new = sys.argv[1]
snew = str(new)
print type(snew)
ipcheck(new)

另外,我尝试用另一种方式来做,但总是出现错误,是否可以通过“或 |”运算符在if循环中传递两个参数?我该怎么做呢?

#if (matchip | matchany) :  
    #print "the ip address is valid"
#else:
    #print "Invalid Destination IP"


Error
========================

user@bt:/home# ./ipregex.py a
<type 'str'>
Traceback (most recent call last):
File "./ipregex.py", line 21, in <module>
ipcheck(new)
File "./ipregex.py", line 15, in ipcheck
matchany = re.match(anypattern,ip)
File "/usr/lib/python2.5/re.py", line 137, in match
return _compile(pattern, flags).match(string)
File "/usr/lib/python2.5/re.py", line 237, in _compile
raise TypeError, "first argument must be string or compiled pattern"
TypeError: first argument must be string or compiled pattern

==========================================================

编辑

我试图在不编译正则表达式的情况下匹配IP地址。所以我修改了脚本来实现这个功能。结果出现了这个错误:

错误

user@bt:/home# ./ipregex.py a
<type 'str'>
Traceback (most recent call last):
File "./ipregex.py", line 21, in <module>
ipcheck(new)
File "./ipregex.py", line 15, in ipcheck
matchany = anypattern.match(ip)
AttributeError: 'builtin_function_or_method' object has no attribute 'match'

==========================================================

编辑#2

我在一个更简单的代码版本中重现了我的错误。我到底哪里出错了????

#!/usr/bin/python

import sys
import re

def ipcheck(ip):
    anypattern = any
    cpattern = re.compile(anypattern)
    global matchany
    matchany = cpattern.match(ip)
    if matchany:
            print "ip match: %s" % matchany.group()
new = sys.argv[1]
ipcheck(new)

错误

user@bt:/home# ./test.py any
Traceback (most recent call last):
File "./test.py", line 14, in <module>
ipcheck(new)
File "./test.py", line 8, in ipcheck
cpattern = re.compile(anypattern)
File "/usr/lib/python2.5/re.py", line 188, in compile
return _compile(pattern, flags)
File "/usr/lib/python2.5/re.py", line 237, in _compile
raise TypeError, "first argument must be string or compiled pattern"
TypeError: first argument must be string or compiled pattern

2 个回答

0

这个正则表达式可能更好:

((([1-2]?[0-9]?[0-9]\.){1,3}([1-2]?[0-9]?[0-9])?)|any)

它可以匹配像这样的内容:

127.0.0.1
127.0.0
127.0
127.
192.168.1.1
any

你的正则表达式在处理上面的内容时会有问题,因为它不匹配 0

补充:

我之前忽略了要匹配 任何 的部分。

这个正则表达式会匹配一些无效的地址,不过如果你只是想在日志文件中搜索,这样也没问题。如果你需要非常准确的匹配,可以看看 这个链接

1

当你使用 re.compile 时,你会在编译后的对象上调用 match 函数,比如 ippattern.match(ip)。另外,如果你想从一个 MatchObject 中获取匹配到的 IP,可以使用 MatchObject.group()。我对你的例子做了一些修改,现在应该能满足你的需求:

#!/usr/bin/python

import sys
import re

def ipcheck(ip):
    ippattern_str = '(([1-2]?[\d]{0,2}\.){1,3}([1-2]?[\d]{0,2})|any)'

    ippattern = re.compile(ippattern_str)
    # ippattern is now used to call match, passing only the ip string
    matchip = ippattern.match(ip)
    if matchip:
        print "ip match: %s" % matchip.group()

if len(sys.argv) > 1:
    ipcheck(sys.argv[1])

一些结果:

[ 19:46 jon@hozbox ~/SO/python ]$ ./new.py 100.
ip match: 100.
[ 19:46 jon@hozbox ~/SO/python ]$ ./new.py 100.1.
ip match: 100.1.
[ 19:46 jon@hozbox ~/SO/python ]$ ./new.py 100.1.55.
ip match: 100.1.55.
[ 19:46 jon@hozbox ~/SO/python ]$ ./new.py 100.1.55.255
ip match: 100.1.55.255
[ 19:47 jon@hozbox ~/SO/python ]$ ./new.py any
ip match: any
[ 19:47 jon@hozbox ~/SO/python ]$ ./new.py foo
[ 19:47 jon@hozbox ~/SO/python ]$ 

撰写回答