re.sub()
does not work on the client side.
Are there any plans to implement it any time soon?
re.sub()
does not work on the client side.
Are there any plans to implement it any time soon?
While waiting for the real thing my workaround is to use this:
def re_sub(pattern, repl, text):
groups = re.match(pattern, text)
if groups:
for i in range(1, groups.lastindex + 1):
repl = repl.replace('\\{}'.format(i), groups[i])
return repl
It works just fine with simple cases like:
>>> re_sub('(\d{3}).*(\d{3}).*(\d{4})', r'(\1) \2-\3', '1234567890')
'(123) 456-7890'
>>> re_sub('(\d{3}).*(\d{3}).*(\d{4})', r'(\1) \2-\3', '123 456 7890')
'(123) 456-7890'
I made this solution for myself since it’s 2020’oct but re.sub still not supported in anvil.works:
def re_sub(pattern, repl, text):
result = ""
while True:
m = re.search(pattern, text)
if m is None:
result += text
break
if len(result) > 0:
pass
s = text.index(m.group(0))
e = s + len(m.group(0))
result += text[:s] + repl
text = text[e:]
return result
Here is an updated version of my old function that works on multiline strings containing \n
:
def re_sub(pattern, repl, text):
texts_1 = text.split('\n')
texts_2 = [repl] * len(texts_1)
for n_text in range(len(texts_1)):
matches = re.match(pattern, texts_1[n_text])
if matches:
for n_match, match in enumerate(matches.groups(), 1):
texts_2[n_text] = texts_2[n_text].replace(f'\\{n_match}', match or '')
else:
texts_2[n_text] = texts_1[n_text]
return '\n'.join(texts_2)
Here is a solution I’ve come up with. I put this code into a utils module that I can use anywhere in my client code.
Instead of calling:
import re
Call:
from .my_module import re
Place this code in “my_module”
""" GET MODULES """
def get_re():
""" Get re module with sub function added """
global re
import re
regex = re
def sub(pattern, repl, string, count=0, flags=0):
"""Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable;
if a string, backslash escapes in it are processed. If it is
a callable, it's passed the Match object and must return
a replacement string to be used."""
if isinstance(pattern, str):
pattern = re.compile(pattern, flags)
if isinstance(string, str):
pattern = re.compile(pattern, flags)
matches = pattern.findall(string)
if isinstance(count, int) and count > 0:
matches = matches[:count]
for match in matches:
string = string.replace(match, repl)
return string
regex.sub = sub
re = regex
return re
re = get_re()
Then you can use re.sub as you typically would.
Example:
from .my_module import re
pattern = '[a-z]+'
string = 'Account Number - 12345, Amount - 586.32'
repl = 'AA'
print('Original string')
print(string)
result = re.sub(pattern, repl, string, flags=re.IGNORECASE)
print('After replacement')
print(result)
Note that if you intend to use this updated re in a nested module, you’ll have to load that module after assigning it as such:
re = get_re()
from . import my_nested_module
This will make the “my_nested_module” module available in your utils module and make the re module available in your “my_nested_module” module
And this one works with more than 10 matches:
def re_sub(pattern, repl, text):
texts_1 = text.split('\n')
texts_2 = [repl] * len(texts_1)
for n_text in range(len(texts_1)):
matches = re.match(pattern, texts_1[n_text])
if matches:
groups = matches.groups()
for n_match in range(len(groups) - 1, -1, -1): # go backwards to fill double digit numbers first
texts_2[n_text] = texts_2[n_text].replace(f'\\{n_match + 1}', groups[n_match] or '')
else:
texts_2[n_text] = texts_1[n_text]
return '\n'.join(texts_2)
[I moved this post to Feature Requests.]
Another re.sub alternative in the client, this one taking advantage of Javascript. I’ve found the Javascript regex implementation to be as complete as I’ve needed.
from anvil.js.window import RegExp
from anvil.js.window import String
def sub(pattern, repl, text, flags = 'gmi'):
regex = RegExp(pattern, flags)
result = String.prototype.replace.call(text, regex, repl)
return result
Any other new modules to note, maybe enum or abc ; -)
Best to create a separate feature requests, or add a like/comment to any existing requests.
(fractions
was also added)