# Write code to split a string at uppercase letters # using regular expression, # and print them as string # Example, a string "IWillDoMorePractice" # will result in "I Will Do More Practice" import re text = "IWillDoMorePractice" # sample solution #1 regex = re.compile(r'[A-Z][^A-Z]*') string = "" matches = regex.findall(text) # findall() returns a list of matched string print("matches =", matches) for match in matches: if len(string) > 0: string += " " string += match # match is a string and thus does not support group() print(string) # sample solution #2 regex = re.compile(r'[A-Z][^A-Z]*') matches = regex.finditer(text) # finditer() returns a collection of matched objects print("matches =", matches) string = "" for match in matches: if len(string) > 0: string += " " # match is an object and thus support group(), start(), end() string += match.group() # or match.group(0) print(string) # Consider the following code. Differences? What do they return? # When are they used? print("1", regex.search(text)) print("2", regex.match(text)) print("3", regex.findall(text)) print("4", regex.finditer(text)) print("5", re.findall('[A-Z][^A-Z]*', text)) print("6", re.finditer('[A-Z][^A-Z]*', text)) # let's modify the regular expression to review the concept of grouping print("\n---- grouping concept ----") regex = re.compile(r'([A-Z])([^A-Z]*)') # divide into 2 groups matches = regex.finditer(text) for match in matches: print('match =', match) print(' match.group() = match.group(0) =', match.group()) print(' match.groups() = match.groups(0) =', match.groups()) print(' match.group(1) =', match.group(1)) print(' match.group(2) =', match.group(2)) # notice that since the regular expression is divided into 2 groups, # we can access group 1 and group 2 # (if there're n groups, then we can access group 1, 2, ..., n) print(' match.groups(1) =', match.groups(1)) print(' match.groups(2) =', match.groups(2)) # findall() returns the occurrences of the pattern in the target string # - create a list of occurrences of a pattern in a string # - group(), start(), end() not applicable # search() gives more information than just the actual patterns # - tell where the pattern occurs in the target string # - returns a match object for the first occurrence # - returns None if pattern is not found # match() checks if the pattern exists at the very *start* of a string # - returns None if pattern not found # note: Python processes None as False # finditer() creates a list (or an iterator) of match objects for where # the pattern occurs in a string # - thus, can iterate a list of match objects and use group(), start(), end()