Python之re模块
Python用" \\\\ "表示正则表达式中的" \ ",因为正则表达式中如果要匹配" \ ",需要用\来转义,变成" \\ ",而Python语法中又需要对字符串中每一个\进行转义,所以就变成了" \\\\ "。
为了使正则表达式具有更好的可读性,Python特别设计了原始字符串(raw string) raw string就是用'r'作为字符串的前缀,如 r"\n":表示两个字符"\"和"n",而不是换行符了。Python中写正则表达式时推荐使用这种形式。
例如:funshion.com 可以使用?funshion\\.com?或者r?funshon\.com?进行匹配 需要提醒你的是,在写文件路径的时候就不要使用raw string了,这里存在陷阱。 一:Re模块正则匹配:
(1)
\d 匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s 匹配任何空白字符;它相当于类 [ fv]。
\S 匹配任何非空白字符;它相当于类 [^ fv]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。
具有重复功能的元字符:
* 对于前一个字符重复0到无穷次
+对于前一个字符重复1到无穷次
?对于前一个字符重复0到1次
{m,n} 对于前一个字符重复次数在为m到n次,其中,{0,} = *,{1,} = , {0,1} = ? {m} 对于前一个字符重复m次
(2)^和$
m = re.search(r'(www\.)?funshion\.com',str)
可以匹配funshion.com XXX.funshion.com
m = re.search(r'^(www\.)?funshion\.com',str)
可以匹配和 funshion.com
在元字符[]中,"^"在不同位置所代表的意义。
>>>re.search("[^abc]","abcd") #"^"在首字符表示取反,即abc之外的任意字符。 <_sre.SRE_Match object at 0x011B19F8>
>>> m=re.search("[^abc]","abcd")
>>>m.group()
'd'
>>> m=re.search("[abc^]","^") #如果"^"在[ ]中不是首字符,那么那就是一个普通字符
>>>m.group()
'^'
元字符($)匹配字符串的结尾或者字符串结尾的换行之前。
>>>m=re.search("foo.$","foo1\nfoo2\n",re.MULTILINE)
>>>print m.group()
foo1
(3)有几点注意的地方:
1.{m.n}用来表示前面正则表达式重复m到n次,尝试匹配尽可能多的copy。
>>>re.findall("a{2,4}","aaaaaaaa")
['aaaa', 'aaaa']
#可以看到{m,n},正则表达式优先匹配n,而不是m,因为结果不是["aa","aa","aa","aa"] >>>re.findall("a{2}","aaaaaaaa")
['aa', 'aa', 'aa', 'aa']
#匹配重复两次
>>>re.findall("a{2,4}?","aaaaaaaa")
['aa', 'aa', 'aa', 'aa']
#{m,n}? 用来表示前面正则表达式的m到n次copy,尝试匹配尽可能少的copy
2.元字符“.”在默认模式下,匹配除换行符外的所有字符。在DOTALL模式下,匹配所有字符,包括换行符。
>>> m=re.match(".","\n")
>>> print m
None
>>> m=re.match(".","\n",re.DOTALL)
>>>print "#",m.group(),"#"
#
#
3.可以将匹配模式赋值给变量:
>>>pat=?[a-zA-Z]+?
>>>text=?”Hm…Er…funshion?”funshion!?
>>>m=re.findall(pat,text)
>>>print m
['Hm', 'Er', 'funshion', 'funshion']
re模块主要函数
re.compile(pattern, flags=0)
编译正则表达式,返回RegexObject对象,然后可以通过RegexObject对象调用match()和search()方法。
prog = re.compile(pattern)
result = prog.match(string)
跟
result = re.match(pattern, string)
是等价的。
re.search()和re.match()
str=
m = re.match(r'www',str) m不为None
等同于 m=re.search(r?^www?,str)
m = re.match(r'com',str) m等于None
m=re.search(r?com?,str) m不为None
re.split(pattern, string, maxsplit=0)
通过正则表达式将字符串分离。如果用括号将正则表达式括起来,那么匹配的字符串也会被列入到list中返回。maxsplit是分离的次数,maxsplit=1分离一次,默认为0,不限制次数。默认分割符为空格。
>>>re.split('\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>>re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>>re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
特别的:可以利用split(?\n?)去掉末尾的换行符
re.findall()
匹配所有子串,并把它们作为一个列表返回。从左到右有序地返回;如果无匹配,返回空列表。
>>>re.findall("a","bcdef")
[]
>>>re.findall(r"\d+","12a32bc43jf3")
['12', '32', '43', '3']
特别的:
>>>a="abcdfa\na1b2c3"
>>>m=re.findall("^a\w+",a,re.MULTILINE)
>>>print a,m.group(0)
['abcdfa', 'a1b2c3']
>>>m=re.findall(r"^\d+","12a,32c,\n43j,3",re.MULTILINE)
>>>print m
['12', '43']
多行匹配方式(包含\n)只有在multiline下可以进行。rearch和match匹配到就返回,不能匹配到多个结果,findall可以匹配多个结果。上述结果可以验证,^是匹配换行符之后,结果提示可以利用“^”在MULTILINE模式可以匹配字符”\n”后的字符
re.sub()
使用给定的替换内容将匹配模式的子字符串替换掉
>>>pat=?{name}?
>>>text=? hi {name}?
>>>m=re.sub(pat,?funshion?,text)
>>>print m
hifunshion
re.finditer(pattern, string, flags=0)
找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。这个匹配是从左到右有序地返回。如果无匹配,返回空列表。
>>>it = re.finditer(r"\d+","12a32bc43jf3") >>> for match in it:
>>> print match.group()
12
32
43
3
第二篇:python嵌入c++总结
Python嵌入C++接口总结
零、目录
一、环境配置
二、程序架构
三、Python和C++里的数据结构切换
四、遇到的一些问题
一、环境配置
1、 首先在properties里面的include.path添加python/include
2、 其次在properties里的library.path添加python/libs
3、 将python里的python2.6.lib修改成?python26_d.lib,因为原来库文件里面的那个
lib不是debug版的,需要只需要修改名字就行了;或者修改头文件里面的配置
python2.6.lib在python安装目录里的python/libs里面
4、 然后在properties里面的linker——input,additional path 添加python26_d.lib;
二、程序结构
1、首先要添加头文件:#include<Python.h>
2、在要调用python文件的地方,要启动python解释器,在用完python解释器后,要释放
python解释器,于是调用python文件要在启动Python解释器和和释放 之间;
下面是一般的程序架构:
//使用python之前,要调用Py_Initialize();这个函数进行初始化
Py_Initialize();
//这是直接执行python语句,如果在调用的python文件里面已经有的话就不需要了。
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");//把当前目录设为当前路径添加python文件
加载python文件
PyObject * pModule = NULL, * first, * second;
pModule =PyImport_ImportModule("add_item");//这里是要调用的文件名
加载无参数函数
second= PyObject_GetAttrString(pModule, "show");//这里是要调用的函数名
PyEval_CallObject(second, NULL);//调用函数
设置函数的参数堆栈
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, pList);
PyTuple_SetItem(pArgs, 1, pDict);
first = PyObject_AttrString(pModule, “parameter ”);
PyEval_CallObject(first, pArgs);
。 。 。 。 。
Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。
三、Python和C++里的数据结构切换
Python提供了6中基本数据结构:
整型,浮点型,字符串,元组,列表,字典;
构造python的基本数据类型:
Py_BuildValue("s", name);
Py_BuildValue("i", name);
Py_BuildValue("f", name);
返回一个PyObject *
元组:
添加元素:
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, pList);
PyTuple_SetItem(pArgs, 1, pDict);
注意:元组在赋值之后就不能改变,要改变的话只能重新生成
列表:
添加元素:
PyList_SetItem(pList, 0, Py_BuildValue("s",x_name));
PyList_SetItem(pList, 1, Py_BuildValue("s",y_name));
返回列表长度:
PyList_GET_SIZE(list)
返回列表第I个元素:
PyList_GET_ITEM(list,i)
返回PYTOHN类型的C++中的字符串:
PyString_AsString(PyObject * string)
添加一项:
PyList_Append(pList, Py_BuildValue("s", name));
插入一项:
PyList_insert(pList,I, Py_BuildValue("s", name));
字典:
PyObject* pDict = PyDict_New();
PyDict_SetItemString(pDict, "first", Py_BuildValue("i", 1));
PyDict_SetItemString(pDict, "second", Py_BuildValue("i", 1));
四、遇到的一些问题
1、首先python文件里面只能有函数,和一些常量值,比如字符串,整型,常量字典,不可以有可变的变量,以为C不会给python文件分配内存;如果在程序里,试图去改变python文件里面的常量,那么这个函数就不会执行下去,所以在编写python接口程序时候,需要分配内存的变量需要在c++程序里面定义,然后通过接口传递给函数:所以接口的重要行,全局变量什么的都一定不要出现;
2、python文件里面的格式比较严格,不能有注释,不能有空行
附录:
1、 C++的调用程序;
2、 被调用的python程序
C++程序:
#include<Python.h>//前面所做的一切配置都是为了调用这个头文件和相关库
#include<iostream>
using namespace std;
int main()
{
Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject * pModule = NULL, * first = NULL, * second = NULL;//声明变量
pModule =PyImport_ImportModule("add_item");//这里是要调用的文件名
//无参数调用
second= PyObject_GetAttrString(pModule, "show");//这里是要调用的函数名
PyEval_CallObject(second, NULL);//调用函数
//有参数函数调用
//PyObject* pDict = PyModule_GetDict(pModule);
first= PyObject_GetAttrString(pModule, "add_item");//这里是要调用的函数名
PyObject * pArgs = NULL, * pList = NULL;
//构造列表
pList = PyList_New(2);
PyList_SetItem(pList, 0, Py_BuildValue("s",x_name));
PyList_SetItem(pList, 1, Py_BuildValue("s",y_name));
PyList_Append(pList, Py_BuildValue("s", "the third"));
//构造字典
PyObject* pDict = PyDict_New();
PyDict_SetItemString(pDict, "first", Py_BuildValue("i", 1));
PyDict_SetItemString(pDict, "second", Py_BuildValue("i", 1));
//设置参数,用元组封装
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, pList);
PyTuple_SetItem(pArgs, 1, pDict);
PyEval_CallObject(first, pArgs);//调用函数
//PyEval_CallObject(first,NULL);
Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。
system("pause");
return 0;
}
PYTHON 程序:
def add_item(mylist, mydict):
print "have reach this"
print mylist,'\n',mydict
def show():
print "can work"