Python 语言本身不支持正则表达式,依赖 re 模块(python1.5 版本被引入)支持正则表达式。有搜索和匹配两种方法完成匹配模式。re 模块常用的函数和方法有 complie、match、search、find 与 findall 等。在利用 re 进行匹配之前,模式必须被编译成 regex 对象。
语法 | 说明 | 示例 |
---|---|---|
. | 匹配除换行符 \n 以外的任意字符 | b.c 匹配 bac,bdc |
* | 匹配前一个字符 0 次或多次 | b*c 匹配 c,或者 bbbc |
+ | 匹配前一个字符 1 次或多次 | b+c 匹配 bc 或者 bbbc |
? | 匹配前一个字符 0 或 1 次 | b?c 匹配 c 或者 bc |
{m} | 匹配前一个字符 m 次 | b{2}c 匹配 bbc |
{m,n} | 匹配前一个字符 m 至 n 次 | b{2,5}c 匹配 bbc 或者 bbbbc |
[abc] | 匹配 [] 内的任意字符 | [bc] 匹配 b 或者 c |
\d | 匹配数字 [0-9] | b\dc 匹配 b1c 等 |
\D | 匹配非数字,等价于 [^\d] | b\Dc 匹配 bAc |
\s | 匹配空白字符 | b\sc 匹配 b c |
\S | 匹配非空白字符 [\^s] | b\Sc 匹配 bac |
\w | 匹配 [A-Za-z0-9_] | b\wc 匹配 bAc 等 |
\W | 等价于 [^\w] | b\Wc 匹配 b c |
\ | 转义字符, | b\\c 匹配 b\c |
^ | 匹配字符串开头 | ^bc 匹配句首的 bc |
$ | 匹配字符串末尾 | bc$ 匹配以 bc 结尾的字符串 |
\A | 仅匹配字符串开头 | \Abc 匹配字符串开头的 bc |
\Z | 仅仅匹配字符串末尾 | bc\Z 匹配字符串末尾的 bc |
| | 匹配左右表达式任意一个 | b|c 匹配 b 或者 c |
线程是一个单一的执行流程,它是所有程序执行过程中最小的控制单位,即能被 CPU 所调度的最小任务单元。在 Perl 中一个线程的生命周期包括创建,运行与退出这三个阶段。线程的运行过程与普通函数的执行类似,但新建线程的执行与当前线程的执行是并行的。
在 Perl 中创建线程有两种方法:
清单 2. 使用 threads 包的 create() 方法
use threads; sub say_hello { printf("Hello thread! @_.\n"); return( rand(10) ); } my $t1 = threads->create( \&say_hello, "param1", "param2" ); |
清单 3. 使用 async{} 块创建线程
#!/usr/bin/perl use threads; my $t4 = async{ printf("Hello thread!\n"); }; |
对于线程的执行控制,有两种方式,一种是 join(),一种是 detach()。所谓 join() 就是在主线程中等待子线程的执行返回值,然后再继续执行后续代码,而在调用线程的 join() 方法之前,子线程与主线程的执行是分开的。而 detach() 则是告诉解释器主线程不关心子线程的执行结果,所以该子线程在完成任务之后就是自动退出,同时释放自己所占有的资源,而不用主线程再操心。
Perl 默认任何数据结构都不是共享的,任何新创建的线程都有当前数据的私有拷贝。如果要共享数据,必须使用 threads::shard 进行显示声明。
如:
my $var :shared = 0; # use :share tag to define my @array :shared = (); # use :share tag to define my %hash = (); share(%hash); # use share() funtion to define |
同时 Perl 线程还支持锁机制,可以使用 lock 方法实现线程间共享数据的锁机制。Perl 中的 Thread::Semaphore 包为线程提供了信号量的支持,Thread::Queue 包为线程提供了线程安全的队列支持。更多使用读者可以自行查阅相关文档。
Python 提供了几个用于多线程编程的模块,包括 thread, threading 和 Queue 等。thread 和 threading 模块允许程序员创建和管理线程。thread 模块提供了基本的线程和锁的支持,而 threading 提供了更高级别,功能更强的线程管理的功能。Queue 模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。
Python 的线程创建也有两种方式,一是利用 thread 模块的 start_new_thread() 函数来产生新线程。
import time import thread def timer(no, interval): cnt = 0 while cnt<10: print 'Thread:(%d) Time:%s/n'%(no, time.ctime()) time.sleep(interval) cnt+=1 thread.exit_thread() def test(): #Use thread.start_new_thread() to create 2 new threads thread.start_new_thread(timer, (1,1)) thread.start_new_thread(timer, (2,2)) if __name__=='__main__': test() |
另一种是创建 threading.Thread 的子类来包装一个线程对象。
class timer(threading.Thread): # derived from the class threading.Thread def __init__(self, num, interval): threading.Thread.__init__(self) self.thread_num = num self.interval = interval self.thread_stop = False def run(self): #Overwrite run() method, put what you want the thread do here while not self.thread_stop: print 'Thread Object(%d), Time:%s/n' %(self.thread_num, time.ctime()) time.sleep(self.interval) def stop(self): self.thread_stop = True |
Python 线程中也提供同步机制,可以利用 thrading 模块的 threading.RLock 和 hreading.Condition 可以分别实现锁机制和条件变量。
其中 acquire() 和 release() 方法分别获取和释放锁。
def run(self): global x lock.acquire() for i in range(3): x = x + 1 time.sleep(2) print x lock.release() |
更多关于线程的内容,读者可查阅相关文档。
本文从 Perl 和 Python 的起源,基本数据类型、控制结构、函数、包与模块、面向对象、正则表达式以及线程等方面进行了比较,从而给需要同时掌握这两种脚本语言的开发人员一定参考,以便更好的理解与应用。