* 文末 re 模塊速查表php
1. 特殊符號和字符html
. | 任意一個字符 |
.. | 任意兩個字符 |
.end | end 以前的任意一個字符 |
f.o | 匹配 f 和 o 之間的任意字符;如 fao、f9o、f#o |
| java |
擇一匹配的管道符號 <=> []python |
at|home 正則表達式 |
匹配 at、homeshell |
* json |
匹配 0 次或屢次前面出現的正則表達式數組 |
+ cookie |
匹配 1 次或屢次session |
? |
匹配 0 次或 1 次 |
^ |
匹配字符串起始部分 |
$ |
匹配字符串終止部分 |
^From |
任何以 From 起始的字符串 |
From$ |
任何以 From 結尾的字符串 |
^subject:hh$ |
任何由單獨的字符串 subject:hh 構成的字符串 |
.*giur$ |
以 giur 結尾的字符串 |
特殊字符集
特殊字符集 |
|
\d |
匹配任何十進制數(\D 相反)<=> [0-9] |
\w |
任何字母數字(\W 相反) <=> [A-Za-z0-9] |
\s |
任何空格字符(\S 相反) <=> [\n\t\r\v\f] |
\b |
匹配任何單詞邊界 (\B 匹配出如今中間的字符串) |
\A\Z |
匹配字符串起始和結束 <=> ^$ |
\bthe\b |
僅僅匹配單詞 the |
\Bthe |
任何包含但不以 the 做爲起始的字符串 |
\w+-\d+ |
任意字母數字+連字符+數字 "asd123424-1234" |
字符集 & 閉包操做
字符集 & 閉包操做 |
|
[0-9] |
數字 <=> \d |
[a-zA-Z] |
字母 <=> \w |
["-a] |
ASCII 中的字符 |
b[aeiu]t |
匹配 bat、bet、bit、but |
[cr][23][dp][o2] |
匹配 c2do、r3p2、r2d2、c3po |
[r-u][env-y][us] |
r|s|t|u 跟 e|n|v|w|x|y 跟 u|s |
[^aeiou] |
非 a|e|i|o|u 字符 |
[^\t\n] |
不匹配製表符或 \n |
[dn]ot? |
do、no、dot、not |
0?[0-9] |
任意數字,可前置 0 |
[0-9]{15,16} |
匹配 15 或 16 個數字 |
</?[^>]+> |
匹配全部 html 標籤 |
\d{3}-\d{3}-\d{4} |
電話號碼格式 "800-555-1212" |
圓括號指定分組
一對圓括號能夠實現對正則表達式進行分組、匹配子組
圓括號分組匹配使得findall返回元組,元組中,幾對圓括號就有幾個元素,保留空匹配
擴展表示法 **
儘管有圓括號,但只有 (?P<name>) 表述一個分組匹配,其餘的都沒有建立一個分組
擴展表示法 ** |
|
(?iLmsux) |
編譯選項指定,能夠寫在findall或compile的參數中,也能夠寫在正則式裏 |
(?#...) |
表示註釋,全部內容被忽略 |
(?:...) |
表示一個匹配不用保存的分組 |
(?=...) |
若是 ... 出如今要匹配字符串的後面 例如:Isaac (?=Asimov) 只匹配 'Isaac ' 後面跟 'Asimov'的字符串 |
(?!...) |
若是 ... 不出如今要匹配字符串後面 |
(?<=...) |
若是 ... 出如今以前的位置,則匹配 |
(?<!...) |
若是 ... 不出如今以前的位置,則匹配 |
(?(id/name)yes-pattern|no-pattern) |
若是 group 中的 id/name 存在匹配 yes-pattern,不然 no-pattern 例如:(<)?(\w+@\w+(?:\.\w+)+)(?(1)>)只會匹配 <user@host.com> 或者 user@host.com 不會匹配 <user@host.com |
(?<!192\.168) |
若是一個字符串以前不是 192.168. 才作匹配 |
(?P<name>)和(?P=name)能夠同時使用,前者除了原有的編號外再指定一個額外的別名,後者引用別名爲<name>的分組匹配到字符串
2. re 常見屬性
2.1 compile()
編譯正則表達式模式,返回一個對象的模式。
2.2 match()
match()從字符串起始對模式進行匹配,匹配對象的 group() 用於顯示成功的匹配
2.3 search()
掃描字符串查找正則表達式模式產生匹配的第一個位置,並返回MatchObject實例,不然返回None
2.4 findall & finditer()
findall() 查詢字符串中某個模式所有的非重複出現狀況
finditer() 在匹配對象中迭代,找到 RE 匹配的全部子串,並把它們做爲一個迭代器返回
2.5 sub() subn()
將某字符串中全部匹配正則表達式的部分進行某種形式的替換
sub()返回替換後的字符串
subn()返回替換後的字符串和替換總數組成的元組
2.6 split()
在限定模式上使用split()分隔字符串
此示例 DATA 爲用戶輸入,輸入內容多是城市和州名,或城市加上ZIP編碼,或者三者同時輸入
3. 正則表達式示例
3.1 經過正則表達式檢測日誌中的注入
get.txt 保存正則表達式規則
\.\./ \:\$ \$\{ select.+(from|limit) (?:(union(.*?)select)) having|rongjitest sleep\((\s*)(\d*)(\s*)\) benchmark\((.*)\,(.*)\) base64_decode\( (?:from\W+information_schema\W) (?:(?:current_)user|database|schema|connection_id)\s*\( (?:etc\/\W*passwd) into(\s+)+(?:dump|out)file\s* group\s+by.+\( xwork.MethodAccessor (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\( xwork\.MethodAccessor (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ java\.lang \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ \<(iframe|script|body|img|layer|div|meta|style|base|object|input) (onmouseover|onerror|onload)\=
regexRules.py 把規則加載爲 json
regexes = { "regex": { "get": [], "post":[] }, "update": "20170828" } fp = open("get.txt") regexRule = fp.readlines() for reg in regexRule: regexes["regex"]["get"].append({"reg":reg.rstrip('\n')}) # print regexes fp.close()
logAnalys.py 主函數,讀取每條日誌,逐條規則進行匹配
# -*- coding: UTF-8 -*- import re import sys import urllib from regexRules import regexes reload(sys) sys.setdefaultencoding('utf8') #-----------------search bad data---------------- def checkData(uri): uri = unicode(str(uri), errors='ignore') uri = urllib.unquote(uri).lower() regexList=regexes["regex"]["get"] for i in range(len(regexList)): regRule=regexList[i] try: pattern = re.compile(r'%s'%(regRule["reg"])) except: print regRule["reg"] match = pattern.search(uri) if match: return 1 #-------------Reduce useless param-------------- def reduParam(url): try: values = url.split('?',1)[1] return values except: pass #---------------------main---------------------- def analysLog(logPath): index = 0 fp = open(logPath) while 1: line = fp.readline() if not line: break index += 1 tmpValue = reduParam(line) if tmpValue: if(checkData(tmpValue)): print '%s - - %s'%(index,line) if __name__ == '__main__': analysLog('access.log')
常見正則表達式符號和特殊字符
表示法 |
描述 |
正則表達式示例 |
符號 |
||
re1|re2 |
匹配正則表達式re1或re2 |
foo|bar |
. |
匹配任意除換行符"\n"外的字符 |
a.c |
^ |
匹配字符串開頭,在多行模式中匹配每一行的開頭 |
^Dear |
$ |
匹配字符串末尾,在多行模式中匹配每一行的末尾 |
/bin/*sh$ |
* |
匹配前一個字符0或屢次 |
[A-Za-z0-9]* |
+ |
匹配前一個字符1次或屢次 |
[a-z]+\.com |
? |
匹配一個字符0次或1次 |
goo? |
{} |
{m}匹配前一個字符m次,{m,n}匹配前一個字符m至n次 |
[0-9]{3} ,[0-9]{5,9} |
[...] |
匹配字符集中的任意單個字符 |
[aeiou] |
[^...] |
不匹配字符集中的任意一個字符 |
[^aeiou],[^A-Za-z0-9] |
[x-y] |
X~y範圍中的任何一個字符 |
[b-x] |
() |
匹配封閉的正則,存爲子組,從表達式左邊開始每遇到一個分組的左括號「(」,編號+1 |
([0-9]{3})?,f(oo|u)bar |
特殊字符 |
||
\d |
匹配任何十進制數(\D 相反)<=> [0-9] |
data\d+.txt |
\w |
任何字母數字(\W 相反) <=> [A-Za-z0-9] |
[A-Za-z]\w+ |
\s |
任何空格字符(\S 相反) <=> [\n\t\r\v\f] |
of\sthe |
\b |
匹配任何單詞邊界(\B相反) |
\bThe\b |
\A(\Z) |
匹配字符串起始(結束) <=> ^($) |
\ADear |
擴展表示法 |
||
(?iLmsux) |
編譯選項指定,能夠寫在findall或compile的參數中,也能夠寫在正則式裏 |
(?x), (?im) |
(?#...) |
表示註釋,全部內容被忽略 |
(?#comment) |
(?:...) |
表示一個匹配不用保存的分組 |
(?:\w+\.) |
(?=...) |
若是 ... 出如今要匹配字符串的後面 例如:Isaac (?=Asimov) 只匹配 'Isaac ' 後面跟 'Asimov'的字符串 |
(?=.com) |
(?!...) |
若是 ... 不出如今要匹配字符串後面 |
(?!.net) |
(?<=...) |
若是 ... 出如今以前的位置,則匹配 |
(?<=800-) |
(?<!...) |
若是 ... 不出如今以前的位置,則匹配 |
(?<!192\.168\.) |
(?(id/name)yes-pattern|no-pattern) |
若是 group 中的 id/name 存在匹配 yes-pattern,不然 no-pattern 例如:(<)?(\w+@\w+(?:\.\w+)+)(?(1)>)只會匹配 <user@host.com> 或者 user@host.com 不會匹配 <user@host.com |
(?(1)y|x) |
(?P<name>...) |
分組,除了原有的編號外再指定一個額外的別名 |
(?P<id>abc){2} |
(?P=name) |
引用別名爲<name>的分組匹配到字符串 |
(?P<id>\d)abc(?P=id) |
常見的正則表達式屬性
函數/方法 |
描述 |
re模塊函數 |
|
re.compile(pattern, flags=0) |
使用可選的標記編譯正則表達式的模式,返回一個正則表達式對象,能夠提升正則的匹配速度,重複利用正則表達式對象。 |
re模塊函數和正則表達式對象方法 |
|
re.match(pattern,string, flags=0) |
若是字符串開頭的零個或多個字符與正則表達式模式匹配,則返回相應的MatchObject實例,不然返回None |
re.search(pattern, string, flags=0) |
掃描字符串查找正則表達式模式產生匹配的第一個位置,並返回MatchObject實例,不然返回None |
re.findall(pattern, string, flags=0) |
返回字符串中模式的全部非重疊匹配,做爲字符串列表返回 |
re.finditer(pattern, string, flags=0) |
與findall()函數相同,但返回的是一個迭代器,對於每一次匹配,迭代器都返回一個匹配對象 |
re.split(pattern, string, maxsplit=0, flags=0) |
根據正則表達式的模式分隔符,split函數將字符串分割爲列表,返回成功匹配的列表,分隔最多操做maxsplit次 |
re.sub(pattern, repl, string, count=0, flags=0) |
使用re替換string中每個匹配的子串後返回替換後的字符串 |
re.subn(pattern, repl, string, count=0, flags=0) |
返回替換的總數 |
re.escape(pattern) |
把pattern中,除了字母和數字之外的字符,都加上反斜杆 |
re.purge() |
清除隱式編譯的正則表達式模式 |
常見的匹配對象方法 |
|
group(num=0) |
返回匹配對象 |
groups(default=None) |
返回一個包含全部匹配子組的元組 |
groupdict(default=None) |
返回一個包含全部匹配的命名子組的字典 |
常見的模塊屬性 |
|
re.I 、 re.IGNORECASE |
不區分大小寫 |
re.L 、 re.LOCALE |
根據本地語言環境經過\w\W\b\B\s\S實現匹配 |
re.M 、 re.MULTILINE |
多行匹配,影響^和$ |
re.X 、 re.VERBOSE |
轉義,不然#沒法實現註釋功能 |
re.S 、 re.DOTALL |
使.匹配包括換行在內的全部字符 |
re.U |
根據Unicode字符集解析字符,這個標誌影響\w,\W,\b,\B |
# References
https://docs.python.org/2/library/re.html
http://www.cnblogs.com/tina-python/p/5508402.html