0% found this document useful (0 votes)
11 views25 pages

Python RegEx and Multithreading Guide

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views25 pages

Python RegEx and Multithreading Guide

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

UNIT-III

Regular Expressions: Introduction, Special Symbols and Characters, Res and


Python Multithreaded Programming: Introduction, Threads and Processes,
Python, Threads, and the Global Interpreter Lock, Thread Module, Threading
Module, Related Modules.

Regular Expression (RegEx)

It is a powerful tool used to search, match, validate, extract or modify text


based on specific patterns. In Python, the built-in re module provides
support for using RegEx. It allows you to define patterns using special
characters like \d for digits, ^ for the beginning of a string and many more.

import re

txt = 'GeeksforGeeks: A computer science portal for gvpcollege'

match = [Link](r'portal', txt)

if match:

print([Link]())

print("Start:", [Link](), "End:", [Link]())

else:

print("No match")

output:

portal

Start: 34 End: 40
use of RegEx
Regular expressions are widely used in various fields involving text
manipulation and analysis.
some of the common use cases:

Use Case Description

Quickly extract emails, phone numbers, URLs, etc. from


Data Mining large text blocks.

Validate user inputs like email addresses, passwords,


Validation dates, etc.

Text Replace or reformat strings to match required formats (e.g.,


Processing date reformatting).
MetaCharacters In RegEx
These are used in functions of module re. Below are the lists of meta characters.
MetaCharacters Description

\ Used to drop the special meaning of character following it

[] Represent a character class

^ Matches the beginning

$ Matches the end

. Matches any character except newline

| Means OR (Matches with any of the characters separated by it.

? Matches zero or one occurrence

* Any number of occurrences (including 0 occurrences)

+ One or more occurrences

{} Indicate the number of occurrences of a preceding RegEx to match.

() Enclose a group of RegEx


Special Sequences
Special sequences in Python RegEx begin with a backslash (\) and are used to match
specific character types or positions in a string.

Special
Sequence Description Examples

Matches if the string begins with the given for geeks


\A \Afor
character

for the
world

Matches if the word begins or ends with geeks


the given character. \b(string) will check for
\b \bge
the beginning of the word and (string)\b will
check for the ending of the word. get

It is the opposite of the \b i.e. the string together


\B should not start or end with the given \Bge
regex. forge

123
Matches any decimal digit, this is
\d \d
equivalent to the set class [0-9]
gee1

geeks
Matches any non-digit character, this is
\D \D
equivalent to the set class [^0-9]
geek1

gee ks
\s Matches any whitespace character. \s
a bc a

a bd
\S Matches any non-whitespace character \S
abcd
Special
Sequence Description Examples

123
Matches any alphanumeric character, this
\w \w
is equivalent to the class [a-zA-Z0-9_].
geeKs4

>$
\W Matches any non-alphanumeric character. \W
gee<>

abcdab
Matches if the string ends with the given
\Z ab\Z
regex
abababab
Basic RegEx Patterns

1. Character Classes
Character classes allow matching any one character from a specified set.
They are enclosed in square brackets [].

import re
print([Link](r'[Gg]ayatri', 'Gayatri Degree college: \
A computer science portal in Gayatri degree college'))
Output
['Gayatri', 'Gayatri']

2. Ranges
In RegEx, a range allows matching characters or digits within a span using -
inside [].
For example, [0-9] matches digits, [A-Z] matches uppercase letters.

import re

print('Range',[Link](r'[a-z A-Z]', 'x'))

Output
Range <[Link] object; span=(0, 1), match='x'>

3. Negation
Negation in a character class is specified by placing a ^ at the beginning of the
brackets, meaning match anything except those characters.

Syntax:
[^a-z]
EX:
import re

print([Link](r'[^a-z]', 'c'))

print([Link](r'G[^e]', 'GVP DEGREE COLLEGE'))


OUTPUT:
None
<[Link] object; span=(0, 2), match='GV'>

4. Shortcuts
Shortcuts are shorthand representations for common character classes.
Some of the shortcuts provided by the regular expression engine.
 \w - matches a word character
 \d - matches digit character
 \s - matches whitespace character (space, tab, newline, etc.)
 \b - matches a zero-length character

Ex:

import re

print('GVP:', [Link](r'\bGVP\b', 'GVP'))

print('GAYATRI VIDYA PARISHAD:', [Link](r'\bGAYATRI\b',


'GAYATRI VIDYA PARISHAD'))

OUTPUT:
GAYATRI VIDYA PARISHAD: <[Link] object; span=(0, 7), match='GAYATRI'>

4. Beginning and End of String


The ^ character chooses the beginning of a string and the $ character chooses
the end of a string.

5. Any Character
The . character represents any single character outside a bracketed character
class.

import re

print('Any Character', [Link](r'[Link].n', 'python 3'))


OUTPUT:
Any Character <[Link] object; span=(0, 6), match='python'>

[Link]
Repetition enables you to repeat the same character or character class.
Consider an example of a date that consists of day, month, and year.

Use a regular expression to identify the date (mm-dd-yyyy).


import re

print('Date{mm-dd-yyyy}:', [Link](r'[\d]{2}-[\d]{2}-[\d]{4}','18-08-2020'))
OUTPUT:

Date{mm-dd-yyyy}: <[Link] object; span=(0, 10), match='18-08-2020'>

[Link]
Grouping is the process of separating an expression into groups by using
parentheses, and it allows you to fetch each individual matching group.

import re
grp = [Link](r'([\d]{2})-([\d]{2})-([\d]{4})', '26-08-2020')
print(grp)

OUTPUT:

<_sre.SRE_Match object; span=(0, 10), match='26-08-2020'>

9. Lookahead
In the case of a negated character class, it won't match if a character is
not present to check against the negated character. We can overcome
this case by using lookahead; it accepts or rejects a match based on the
presence or absence of content.

import re
print('negation:', [Link](r'n[^e]', 'Python'))
print('lookahead:', [Link](r'n(?!e)', 'Python'))
Output:
negation: None
lookahead: <[Link] object; span=(5, 6), match='n'>

Lookahead can also disqualify the match if it is not followed by a particular


character. This process is called a positive lookahead, and can be
achieved by simply replacing ! character with = character.

import re

print('positive lookahead', [Link](r'n(?=e)', 'jasmine'))

output:
positive lookahead <_sre.SRE_Match object; span=(5, 6),
match='n'>

Multithreaded
Multithreading is a concept of executing different pieces of code concurrently.
A thread is an entity that can run on the processor individually with its own
unique identifier, stack, stack pointer, program counter, state, register set and
pointer to the Process Control Block of the process that the thread lives on.

Create a Thread

To create a thread, you can use [Link]() class.

Syntax of the Thread() class is:

[Link](group=None, target=None, name=None, args=(),


kwargs={}, *, daemon=None)

 leave group as None.


 target is the callable object to be invoked by
the run() method of Thread.
 name is the Thread name that you can provide and refer to
later in the program.
 args is the argument tuple for the target invocation.
 kwargs is a dictionary of keyword arguments for the target
invocation.
 daemon if set to True, will make the thread a daemon
thread, meaning it will not block the program from exiting.

Start a Thread

Once you have created a thread using the Thread() class, you can
start it using the start() method.

t1 = [Link]()
[Link]()

Wait Until the Thread is Finished

We can make the main thread wait until a specific thread is


finished using the join() method.

[Link]()

Ex;

import threading
def print_one():
for i in range(10):
print(1)
def print_two():
for i in range(10):
print(2)
if __name__ == "__main__":
# create threads
t1 = [Link](target=print_one)
t2 = [Link](target=print_two)
# start thread 1
[Link]()
# start thread 2
[Link]()
# wait until thread 1 is completely executed
[Link]()
# wait until thread 2 is completely executed
[Link]()
# both threads completely executed
print("Done!")

Output
1
1
1
2
2
2
1
1
2
1
2
2
2
2
2
2
1
1
1
1
Done!

Multi-threading with Arguments Passed to Threads

We will pass arguments to the threads


Ex:

import threading
def print_x(x, n):
for i in range(n):
print(x)
if __name__ == "__main__":
# create threads
t1 = [Link](target=print_x, args=(1, 5))
t2 = [Link](target=print_x, args=(2, 10))
[Link]()
[Link]()
[Link]()
[Link]()
print("Done!")

OUTPUT:
12

12

12

12

12

2
2
2
2
2
Done!

Daemon Threads

Daemon threads are threads that run in the background and are
killed automatically when the main program exits, even if they
haven't finished executing. These threads are useful for tasks like
logging or background monitoring where you don't need to wait
for them to finish before the program terminates.

import threading
def background_task():
for i in range(5):
print(f'Background task {i}')
if __name__ == "__main__":
# create daemon thread
t1 = [Link](target=background_task,
daemon=True)
# start thread
[Link]()
# main program finishes here
print('Main program finished!')

output:
Background task 0
Background task 1
Background task 2
Background task 3
Background task 4
Main program finished!
Multiprocessing
Multiprocessing is the ability of the system to handle multiple
processes simultaneously and independently. In a multiprocessing
system, the applications are broken into smaller routines and the OS
gives threads to these processes for better performance.

import multiprocessing

# Function to check even numbers

def print_even(numbers):

for num in numbers:

if num % 2 == 0:

print(f"Even: {num}")

# Function to check odd numbers

def print_odd(numbers):

for num in numbers:

if num % 2 != 0:

print(f"Odd: {num}")

if __name__ == "__main__":
numbers = list(range(1, 21)) # Numbers from 1 to 20

# Create processes
p1 = [Link](target=print_even, args=(numbers,))

p2 = [Link](target=print_odd, args=(numbers,))

# Start processes

[Link]()

[Link]()

# Wait for processes to complete

[Link]()

[Link]()

print("Finished checking even and odd numbers.")

Output:
even: 0
even: 2
even: 4
even: 6
even: 8
even: 10
even: 12
even: 14
odd: 1
odd: 3
odd: 5
odd: 7
odd: 9
odd: 11
odd: 13
END!
Getting information about the processes in Python
We can get the information about the processes running like id and name. We
can also check if the process is currently alive or not.

Getting id of the processes and checking if it is alive


We can use the getpid() function ins the os module to get the id of the
processes. And to know if the process is alive we can use the is_alive() function.
import multiprocessing
from multiprocessing import Process
import os
def func1(): #function to print all even numbers till n
print("Id of Funct1: ",[Link]())
def func2(): #function to print all odd numbers till n
print("Id of Funct2: ",[Link]())
if __name__=="__main__":
print("Id of the main process: ",[Link]())
# creating processes for each of the functions
prc1 = [Link](target=func1)
prc2 = [Link](target=func2)
# starting the 1st process
[Link]()
# starting the 2nd process
[Link]()
print('When the process 1 and 2 started')
alive1='Yes' if prc1.is_alive() else 'No'
print("Is process 1 alive?",alive1)
alive2='Yes' if prc2.is_alive() else 'No'
print("Is process 2 alive?",alive2)
# waiting until 1st process is finished
[Link]()
print('When process 1 is completed and 2 is continuing:')
alive1='Yes' if prc1.is_alive() else 'No'
print("Is process 1 alive?",alive1)
alive2='Yes' if prc2.is_alive() else 'No'
print("Is process 2 alive?",alive2)
# waiting until 2nd process is finished
[Link]()
print('When both the processes are completed:')
alive1='Yes' if prc1.is_alive() else 'No'
print("Is process 1 alive?",alive1)
alive2='Yes' if prc2.is_alive() else 'No'
print("Is process 2 alive?",alive2)
# both processes finished
print("END!")
OUTPUT:
Id of the main process: 14720

When the process 1 and 2 started

Is process 1 alive? Yes

Is process 2 alive? Yes

When process 1 is completed and 2 is continuing:

Is process 1 alive? No

Is process 2 alive? No

When both the processes are completed:

Is process 1 alive? No

Is process 2 alive? No

END!

Getting the name of the process


We can use the name() function multiprocessing module.

import multiprocessing
from multiprocessing import Process,current_process
import os
def func1(): #function to print all even numbers till n
print("Name of Process 1: ",current_process().name)
def func2(): #function to print all odd numbers till n
print("Name of Process 2: ",current_process().name)
if __name__=="__main__":
# creating processes for each of the functions
prc1 = [Link](target=func1,name='Funct 1')
prc2 = [Link](target=func2,name='Funct 2')
# starting the 1st process
[Link]()
# starting the 2nd process
[Link]()
# waiting until 1st process is finished
[Link]()
# waiting until 2nd process is finished
[Link]()
# both processes finished
print("END!")

OUTPUT:

Name of Process 1: Funct 1


Name of Process 2: Funct 2
END!

Locks in Multiprocessing in Python


Similar to multithreading, multiprocessing in Python also supports locks. We
can set the lock to prevent the interference of threads. When the lock is set, a
process starts only when the previous process is finished and the lock is
released.

We can do this by importing the Lock object from the multiprocessing module.

Here also, there are two functions:

1. acquire(blocking=True, timeout=-1):
This function acquires a lock, which can be either blocking or non-blocking.

2. release():
To function releases the lock.

Ex:

import multiprocessing

from multiprocessing import Process,current_process

import os

def func1(): #function to print all even numbers till n

print("Name of Process 1: ",current_process().name)

def func2(): #function to print all odd numbers till n


print("Name of Process 2: ",current_process().name)

if __name__=="__main__":

# creating processes for each of the functions

prc1 = [Link](target=func1,name='Funct 1')

prc2 = [Link](target=func2,name='Funct 2')

# starting the 1st process

[Link]()

# starting the 2nd process

[Link]()

# waiting until 1st process is finished

[Link]()

# waiting until 2nd process is finished

[Link]()

# both processes finished

print("END!")

Output:
Hi
Hi
Hi
Hi
Hi
Hello
Hello
Hello
Hello
Hello
Bye
Bye
Bye
Bye
Bye

Pool Class in Python Multiprocessing


The pool is a class in the multiprocessing module that distributes the tasks to the
available processors in FIFO (First In First Out) manner.

from multiprocessing import Pool


def square(n):
return n**2
if __name__=='__main__':
numbers=[1,5,9]
pool=Pool(processes=3)
print([Link](square,numbers))
Output:
[1, 25, 81]

Global Interpreter Lock

Python Global Interpreter Lock (GIL) is a type of process lock which is used
by python whenever it deals with [Link] only uses only one thread
to execute the set of written statements. This means that in python only one
thread will be executed at a time. The performance of the single-threaded
process and the multi-threaded process will be the same in python and this is
because of GIL in python. We cannot achieve multithreading in python
because we have global interpreter lock which restricts the threads and works
as a single thread.

What problem did the GIL solve for Python :

Python has a reference counter. With the help of the reference counter, we can
count the total number of references that are made internally in python to
assign a value to a data object. Due to this counter, we can count the
references and when this count reaches to zero the variable or data object will
be released automatically.

Example

# Python program showing

# use of reference counter

import sys

a= "gvp"

print([Link](a))

b=a

print([Link](b))

OUTPUT:

4
5

You might also like