<jupyter_start><jupyter_text>search_pattern is a helper function that cross matches several regular expressions against several strings. It visulizes the result by surrounding the matched substring in red border. Only the first matched substring is bordered.  Simple pattern<jupyter_code>patterns =  [
    'ee', # exactly ee
    'ea',  # exactly ea
    'ai',
    'aa'
]
strings = ['tee', 'tea', 'bail']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>One of the pattern Use ```|``` to seperate several pattern<jupyter_code>patterns =  [
    'ee|ea|ai', # ee or ea or ai
]
strings = ['tee', 'tea', 'bail']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Pattern order matters<jupyter_code>patterns =  [
    'oo|ooo', # oo is tried first
    'ooo|oo', # ooo is tried first
]
strings = ['loong', 'looong', 'long']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>When "one of pattern" is followed by or following other regular expressions, use () to seperate to seperate from them<jupyter_code>patterns =  [
    'b(ea|ee)', # b + (ea or ee)
    'bea|ee' # bea or ee
]
strings = ['bead', 'bee']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Qualifiers  appear m to n times Use ```{m,n}```<jupyter_code>patterns =  [
    'ooo', # o, three times
    'o{3}',  # o, three times
    'o{2,3}', # o, 2~3 time
    'o{2, 3}', # o, Not working! Don't put in the blank!    
    'o{2,}', # o, more than 2 times
    'lo{,3}', # l + o, o appears 0 to 3 times
    'o{,3}', # seems not working alone 
]
strings = ['looong', 'long', 'loong']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>appear at least once<jupyter_code>patterns =  [
    'o+n', # o, at least 1 time
    'o{1,}n'# same as above
]
strings = ['looong', 'long', 'bug']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>appear zero or more times<jupyter_code>patterns =  [
    'lo*ng', # long, o appears zero or more time
    'lo{0,}ng' # same as above
]
strings = ['long', 'lng', 'loong', 'leong']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>appear zero or one time<jupyter_code>patterns =  [
    'apples?', # apple, ending s may not appear
    'apples{0,1}' # same as above
]
strings = ['apple', 'apples']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Sub expression use ```()```<jupyter_code>patterns =  [
    'ba(na){2}', # b + na, na appears two times
    'banana', # same as above
    'bana{2}', # ban + a, a appear 2 times,
    'banaa', # same as above
    
]
strings = ['banana', 'banaa']

search_pattern(patterns, strings)
patterns =  [
    '(a+_+){2}', # two consecutive pattern which match a+_+, they are not necessarily the same string
    'a+_+a+_+', # same as above
    'a+_+'
]
strings = ['aa_a__', 'a_', 'a__a_a_']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Character Set  Any character```.``` stands for any character<jupyter_code>patterns =  [
    'b.d', # b + any character + d
    'be..' # b + e + any character + any character
]
strings = ['bed', 'bid','bee', 'benign', 'beed']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any character in a setUse ```[...]```<jupyter_code>patterns =  [
    'b[ei]d', # b + e or i + d
    'bed|bid' # same as above
] 
strings = ['bed', 'bid', 'bee', 'bud']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Use ```-``` for character range<jupyter_code>patterns =  [
    'id_[0-5]', # id_ + any number in 0 to 5
    'id_[012345]' # same as above
]
strings = ['id_1', 'id_6']

search_pattern(patterns, strings)
patterns =  [
    'type_[a-ex]', # type_ + any character in range a to e and x,
    'type_[abcdex]', # same as above
    'type_[a-zA-Z]' # any letter
] 
strings = ['type_a', 'type_b', 'type_x', 'type_Z']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any character not in set Use ```[^...]```<jupyter_code>patterns =  [
    'type_[^a-z]' # type_ + any character not in a to z
] 
strings = ['type_1', 'type_a', 'type_c']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any number Use ```\d```<jupyter_code>patterns =  [
    'id_\d\d', # id_ + any number character + any number character
    'id_[0-9][0-9]' # same as above
]
strings = ['id_12', 'id_0', 'id']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any non-number character Use ```\D```<jupyter_code>patterns =  [
    'e\D',  # e + any character which is not number character
    'e[^0-9]' # same as above
]
strings = ['bee', 'tel', 'te1']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any word charcters Use ```\w```, word character means a-z, A-Z, 0-9 and _<jupyter_code>patterns = [
    '\w+',  # any word character, more than one time
    '[a-zA-Z0-9_]+' # same as above
]
strings = [':id_1.']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any non-word characters Use ```\W```<jupyter_code>patterns =  [
    '\W+', # any non-word character, more than one time
    '[^a-zA-Z0-9_]+'# same as above
]
strings = ['id_1 + id_2']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any space Use ```\s```<jupyter_code>patterns =  [
    '\s.*\s', # blank + any string + blank
    '[\t\n\f\r ].*[\t\n\f\r ]' # same as above
]
strings = ['<NAME>']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Any Non Space<jupyter_code>patterns =  [
    '\S.+\S', # any character except space + any string + any character except space
    '[^\t\n\f\r ].*[^\t\n\f\r ]' # same as above
]
strings = ['on the\ntree']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Escaping As you see, many characters like ```(```,```.```,```+``` have special means in regular expression. If you want to disable these and search for these characters, add ```\``` before them<jupyter_code>patterns =  [
    '($\d+.\d+)', # $ . + are not treated as characters
    '\(\$\d+\.\d+\)' # $ . + are treated as characters
]
strings = ['apple ($3.25)']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Anchor Anchor are searched but won't be part be of the matching result  followed by Use ```(?=...)```<jupyter_code>patterns =  [
    '\w+(?=\.)',  # word character string, followed by comma. the comma is not returned in the matching result
    '\w+\.' # comma is returned in the matching result
]
strings = ['Apple juice.']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Not followed by Use ```(?!...)```<jupyter_code>patterns =  [
    '\w+(?!\.)', # word character string, not followed by comma
    '\w+[^\.]' # word character string, followed by any character which is not comma
]
strings = ['Apple juice.']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Following Use ```(?<=...)```<jupyter_code>patterns =  [
    '(?<=:)\d+', # number character string, following :
    ':\d+' # : + number character string
]
strings = ['apple:10']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>not following Use ```(?<!)```<jupyter_code>patterns =  [
    '(?<!A)\d+', # number character string, not followed by A
    '[^A]\d+' # any character expect A + number character string
]
strings = ['A123 123']


search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>border of word<jupyter_code>patterns =  [
    r'\beat\b', # eat surrounded by border of word, (whole word searching)
    'eat' #
]
strings = ['I eat food', 'beat']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>Why use ```r``` in ```r'\beat\b'```? ```\b``` in python has special meaning (like ```+``` has special meaning in regular expression), it represents a back space character [(see here)](https://stackoverflow.com/questions/25065608/what-does-backward-slash-b-do-in-python) To disable this behaviour, add ```r``` in front of the string. (Like we add ```\``` before ```+``` in regular expression)  not border of word<jupyter_code>patterns =  [
    r'\Beat\B', # eat, not following or followed by word border, (appear within a word)
    'eat'
]
strings = ['I eat food', 'beats']

search_pattern(patterns, strings)<jupyter_output><empty_output><jupyter_text>ExercisesTry to search valid email address<jupyter_code>patterns = [
    '^[^\d@][\w+\.]+@\w+(\.com)?\.(cn|com|org)',
]

strings = [
    '<EMAIL>',
    '<EMAIL>',
    '<EMAIL>',
    '<EMAIL>',
    '@ht.com.cn',
    '<EMAIL>', 
    <EMAIL>',     
]

search_pattern(patterns, strings)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17286055233549266, 'fraction_numerical': 0.00829639731787703, 'mean_word_length': 4.699481865284974, 'pattern_counts': {'":': 0, '<': 120, '<?xml version=': 0, '>': 116, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '6623', 'license': 'MIT', 'n_tokens_mistral': 3298, 'n_tokens_neox': 3216, 'n_words': 799, 'path': '0021_reg_practices/Regular Expression Exercises.ipynb', 'repo_name': 'junjiecai/jupyter_demos', 'size': '8880'}