前些天一直在刷题,不过都是一些挺简单的,然后有几道需要python脚本的题可谓是把我弄了一波,认认真真地去学习了一波python以及正则。就聊一下这几道题收获吧。
Python
Requests
首先是python requests库的学习
对于request的回显如果显示乱码的话,可以添加
rep.encoding = 'utf-8'
进阶用法可以用
r = requests.session()
用来保持会话,以及可以直接实现带cookie二次访问
#比如第一次建立链接
rep = r.get('xxx.com')
#第二次需要post数据,以及以上次的cookie访问
rep2 = r.post('xxx.com',data=data)
这就很方便了,不需要再单独记录cookie来确定是同一次session了
还有python的正则库re
import re
pattern = re.compile(r'^[^=]*')
match = pattern.match(yourString)
if match:
print match.group(0)
在re.compile引号中输入你的正则表达式,然后进行匹配
exec、eval、represents
exec语句用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句。
exec("print('Hello World')")
运行结果:
Hello World
eval语句用来计算存储在字符串中的有效Python表达式。
eval_r("2 * 3")
运行结果:
6
repr函数用来取得对象的规范字符串表示。注意,在大多数时候有eval_r(repr(object)) == object。
执行shell命令
os.system
os模块中的os.system()这个函数来执行shell命令
os.system('ls')
输出结果:
Appalication Desktop Downloads
print os.system('mkdir test')
输出结果:
0
可以看到结果打印出0,表示命令执行成功;否则表示失败(再次执行该命令,输出:子目录或文件 test 已经存在。1)
再次执行:
mkdir: test: File exists
256
注,这个方法得不到shell命令的输出。
popen()
这个方法能得到命令执行后的结果是一个字符串,要自行处理才能得到想要的信息。
import os str = os.popen("ls").read() a = str.split("\n") for b in a: print b
输出结果与
os.system('ls')
一致commands模块
可以很方便的取得命令的输出(包括标准和错误输出)和执行状态位
import commands a,b = commands.getstatusoutput('ls') a是退出状态 b是输出的结果。 >>> import commands >>> a,b = commands.getstatusoutput('ls') >>> print a 0 >>> print b Application Desktop Downloads
commands.getstatusoutput(cmd)返回(status,output)
commands.getoutput(cmd)只返回输出结果
commands.getstatus(file)返回ls -ld file 的执行结果字符串,调用了getoutput,不建议使用这个方法。
subprocess模块
使用subprocess模块可以创建新的进程,可以与新建进程的输入/输出/错误管道连通,并可以获得新建进程执行的返回状态。使用subprocess模块的目的是替代os.system()、os.popen*()、commands.*等旧的函数或模块。
import subprocess subprocess.call(command, shell=True) #会直接打印出结果。 subprocess.Popen(command, shell=True) #也可以是subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) 这样就可以输出结果了。 #如果command不是一个可执行文件,shell=True是不可省略的。 #shell=True意思是shell下执行command
正则表达式
正则表达式自己还是有点弱,主要是一些原理自己有点懒得去了解,就导致每次写正则自己都很蠢…
转载改编自:正则表达式 - 贪婪与非贪婪(惰性)(侵删)
使用场景
有时,我们想用正则匹配以某个子串开头,且以某个子串或字符结尾的子字符串,但是结尾的字串或字符在原字符串中出现了多次,但我们只想匹配从开始处到第一次出现的地方,换句话说,想得到开始和结尾之间内容最少的匹配。
正则的贪婪与非贪婪(惰性)
通常使用如下字符类描述前导字符的重复特征:
?: 告诉引擎匹配前导字符0次或一次。事实上是表示前导字符是可选的。
+: 告诉引擎匹配前导字符1次或多次。
*: 告诉引擎匹配前导字符0次或多次。
{min, max}: 告诉引擎匹配前导字符min次到max次。min和max都是非负整数。如果有逗号而max被省略了,则表示max没有限制;如果逗号和max都被省略了,则表示重复min次。 因此 {0,} 和 * 一样,{1,} 和 + 的作用一样。
贪婪与非贪婪
贪婪 : 默认情况下,? + * {min, max}都是贪婪的,也就是说,它会根据前导字符去匹配尽可能多的内容。
非贪婪(惰性) : 非贪婪就是匹配尽可能少的内容。
原理浅析
结合实例来分析哈基于正则的引擎对文本的匹配过程。原始字符串:This is a <EM>first</EM> test
,使用正则<.+>来匹配HTML标签,期望第一次匹配得到<EM>
,第二次匹配得到</EM>
,实际却是第一次匹配就得到了<EM>first</EM>
。
来看看匹配过程,第一个记号是<
,这是一个文本字符,匹配其自身。第二个符号是.
,匹配了字符E
,然后+
一直可以匹配其余的字符,直到一行的结束。然后到了换行符,匹配失败(.不匹配换行符)。于是引擎开始对下一个正则表达式符号进行匹配,即试图匹配>
。到目前为止,<.+
已经匹配了<EM>first</EM> test
。引擎会试图将>
与换行符进行匹配,结果失败了。于是引擎进行回溯。回溯后的匹配状况是 <.+
匹配 <EM>first</EM> tes
。于是引擎将>
与t
进行匹配。显然还是会失败。这个过程继续,直到 <.+
匹配 <EM>first</EM
,>
与>
匹配。于是引擎找到了一个匹配<EM>first</EM>
。记住,正则导向的引擎是急切的,所以它会急着报告它找到的第一个匹配。而不是继续回溯,即使可能会有更好的匹配,例如<EM>
。所以我们可以看到,由于+
的贪婪性,使得正则表达式引擎返回了一个最左边的最长的匹配。
如果想得到期望的结果,就需要启用非贪婪模式:<.+?>
总结:如果是贪婪匹配模式,正则引擎会一直匹配到字符串最后;当匹配为false时,就回溯以找到倒数第一个匹配位置,返回匹配结果。 如果是非贪婪匹配模式,正则引擎会匹配到符合pattern的末尾位置那个字符,然后再往后走一步,发现匹配为false时,就回溯以找到最近一个匹配为true的位置,返回匹配结果。
实例
例如,原始字符串:
{"accesskey":{"acccessKeyId":"XhUURxsMlJE6EiXf","accessKeySecret":"Q9fMpgBgRnKycMRD28MMkkFMbiNkbY"},"dbGrant":{"0000031736":"READWRITE"},"dbSchemaId":"0000031737"}
现在想把这部分敏感信息替换为空字符串:
"accesskey":{"acccessKeyId":"XhUURxsMlJE6EiXf","accessKeySecret":"Q9fMpgBgRnKycMRD28MMkkFMbiNkbY"},
先不考虑结尾的逗号,尝试正则:"accesskey":\{.+\}
,直接匹配至原始字符串结尾的}字符,因为引擎默认会匹配尽可能多的内容。
考虑到贪婪性,将正则修改为:"accesskey":\{.+\}+?
,匹配结果一样。纳尼?难道我对贪婪性的理解有问题。梳理哈使用姿势,我期望它匹配到开始位置之后出现的第一个}字符,对应的表达式部分为}+?。套用非贪婪模式分析问题,期望对一个或多个}字符进行匹配,且匹配尽可能少的内容,但在原始串中,}字符都是分开的,没有连续,无论如何只能匹配一个单独的}字符。可见对}字符开启非贪婪模式匹配行不通。
想要匹配到开始位置之后出现的第一个}字符 也可以表达为 开始位置和末尾}字符之间的内容最少,对应正则部分修改为:.+?,完整表达式:"accesskey":\{.+?\}
,测试匹配结果,妥妥的。
以上均为转载,这里讲讲自己的实例
sid=14d8f776-a969-4252-b35a-f83a807e7f2d;userName=111111111;
目的是匹配
sid=14d8f776-a969-4252-b35a-f83a807e7f2d;
一开始自己瞎糊弄了半天,最后找到了比较接近的sid=.*;
,可是这个直接匹配到了行末,把userName一起包含进去了,这时候就要考虑到非贪婪性了,即sid=.*?;
就可以匹配到第一个遇到的;
又如
1087080534*1062477688-245892309-863670697+1430950488-2128604487+787613783-929770459-331572804*1754549713+81041939=?;
匹配前面的算数表达式(=
前面的表达式不包括=
)
自己也瞎糊弄了好久,一开始写的是.*=
死活都包含了=,这就很烦了
然后认真去看了正则,用了[^]
,解释是
Match any character that is not in the set.
就是匹配任何不包含这个字符的字符串
所以最后是^[^=]*
还有对于
跑的还不错,给你flag吧: NzI3NTY3
匹配最后的base64字符串,之前考虑的是(?=:).*
但是还是老问题老是匹配了:
…?<
在python中不能用…这就比较麻烦了
然后查了一下发现可以用group
来弄,差不多就是给他们分组的意思
(.*)(: )(.*)
这就分成了三组,第一组匹配的是中文,第二组匹配的是:
,第三组匹配的就是最后的字符串,所以我们只需要提取group(3)
就好了。
Tmux配置记录
详情参考tmux配置
#-- base --#
set -g default-terminal "screen-256color"
set -g display-time 3000
set -g history-limit 10000
set -g base-index 1
set -g pane-base-index 1
set -s escape-time 0
set -g mouse on
#-- bindkeys --#
# split windows like vim. - Note: vim's definition of a horizontal/vertical split is reversed from tmux's
unbind s
bind s split-window -v
bind S split-window -v -l 40
bind v split-window -h
bind V split-window -h -l 120
# navigate panes with hjkl
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# key bindings for horizontal and vertical panes
unbind %
bind | split-window -h # 使用|竖屏,方便分屏
unbind '"'
bind - split-window -v # 使用-横屏,方便分屏
# swap panes
bind ^u swapp -U
bind ^d swapp -D
bind q killp
bind ^e last
unbind r
bind r source-file ~/.tmux.conf \; display "Configuration Reloaded!"
#-- statusbar --#
set -g status-justify centre
set -g status-left "#[fg=red]s#S:w#I.p#P#[default]"
set -g status-right '[#(whoami)#(date +" %m-%d %H:%M ")]'
set -g status-left-attr bright
set -g status-left-length 120
set -g status-right-length 120
set -g status-utf8 on
set -g status-interval 1
set -g visual-activity on
setw -g monitor-activity on
setw -g automatic-rename off
# default statusbar colors
set -g status-bg colour235 #base02
set -g status-fg colour136 #yellow
set -g status-attr default
# default window title colors
setw -g window-status-fg colour244
setw -g window-status-bg default
#setw -g window-status-attr dim
# active window title colors
setw -g window-status-current-fg colour166 #orange
setw -g window-status-current-bg default
#setw -g window-status-current-attr bright
# window title string (uses statusbar variables)
set -g set-titles-string '#T'
set -g status-justify "centre"
set -g window-status-format '#I #W'
set -g window-status-current-format ' #I #W '
# pane border
set -g pane-active-border-fg '#55ff55'
set -g pane-border-fg '#555555'
# message text
set -g message-bg colour235 #base02
set -g message-fg colour166 #orange
# pane number display
set -g display-panes-active-colour colour33 #blue
set -g display-panes-colour colour166 #orange
# clock
setw -g clock-mode-colour colour64 #green
# 修改进入命令模式按键
# remap prefix to Control + a
# set -g prefix C-a
# unbind C-b
# bind C-a send-prefix