From 032d6963d841cea577495917c614dcded1986514 Mon Sep 17 00:00:00 2001 From: mountainsandcode Date: Wed, 4 Apr 2018 15:34:01 +0200 Subject: [PATCH] Add regex functions as templating helpers (#13631) * Add regex functions as templating helpers * Add regex functions as templating helpers - Style fixed * Templating filters, third time lucky? --- homeassistant/helpers/template.py | 37 +++++++++++++++++++++ tests/helpers/test_template.py | 53 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index a04023cfc4f..353fda28875 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -516,6 +516,39 @@ def forgiving_float(value): return value +def regex_match(value, find='', ignorecase=False): + """Match value using regex.""" + if not isinstance(value, str): + value = str(value) + flags = re.I if ignorecase else 0 + return bool(re.match(find, value, flags)) + + +def regex_replace(value='', find='', replace='', ignorecase=False): + """Replace using regex.""" + if not isinstance(value, str): + value = str(value) + flags = re.I if ignorecase else 0 + regex = re.compile(find, flags) + return regex.sub(replace, value) + + +def regex_search(value, find='', ignorecase=False): + """Search using regex.""" + if not isinstance(value, str): + value = str(value) + flags = re.I if ignorecase else 0 + return bool(re.search(find, value, flags)) + + +def regex_findall_index(value, find='', index=0, ignorecase=False): + """Find all matches using regex and then pick specific match index.""" + if not isinstance(value, str): + value = str(value) + flags = re.I if ignorecase else 0 + return re.findall(find, value, flags)[index] + + @contextfilter def random_every_time(context, values): """Choose a random value. @@ -545,6 +578,10 @@ ENV.filters['is_defined'] = fail_when_undefined ENV.filters['max'] = max ENV.filters['min'] = min ENV.filters['random'] = random_every_time +ENV.filters['regex_match'] = regex_match +ENV.filters['regex_replace'] = regex_replace +ENV.filters['regex_search'] = regex_search +ENV.filters['regex_findall_index'] = regex_findall_index ENV.globals['log'] = logarithm ENV.globals['float'] = forgiving_float ENV.globals['now'] = dt_util.now diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 693c3909924..650b98509d0 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -441,6 +441,59 @@ class TestHelpersTemplate(unittest.TestCase): template.Template('{{ utcnow().isoformat() }}', self.hass).render()) + def test_regex_match(self): + """Test regex_match method.""" + tpl = template.Template(""" +{{ '123-456-7890' | regex_match('(\d{3})-(\d{3})-(\d{4})') }} + """, self.hass) + self.assertEqual('True', tpl.render()) + + tpl = template.Template(""" +{{ 'home assistant test' | regex_match('Home', True) }} + """, self.hass) + self.assertEqual('True', tpl.render()) + + tpl = template.Template(""" + {{ 'Another home assistant test' | regex_match('home') }} + """, self.hass) + self.assertEqual('False', tpl.render()) + + def test_regex_search(self): + """Test regex_search method.""" + tpl = template.Template(""" +{{ '123-456-7890' | regex_search('(\d{3})-(\d{3})-(\d{4})') }} + """, self.hass) + self.assertEqual('True', tpl.render()) + + tpl = template.Template(""" +{{ 'home assistant test' | regex_search('Home', True) }} + """, self.hass) + self.assertEqual('True', tpl.render()) + + tpl = template.Template(""" + {{ 'Another home assistant test' | regex_search('home') }} + """, self.hass) + self.assertEqual('True', tpl.render()) + + def test_regex_replace(self): + """Test regex_replace method.""" + tpl = template.Template(""" +{{ 'Hello World' | regex_replace('(Hello\s)',) }} + """, self.hass) + self.assertEqual('World', tpl.render()) + + def test_regex_findall_index(self): + """Test regex_findall_index method.""" + tpl = template.Template(""" +{{ 'Flight from JFK to LHR' | regex_findall_index('([A-Z]{3})', 0) }} + """, self.hass) + self.assertEqual('JFK', tpl.render()) + + tpl = template.Template(""" +{{ 'Flight from JFK to LHR' | regex_findall_index('([A-Z]{3})', 1) }} + """, self.hass) + self.assertEqual('LHR', tpl.render()) + def test_distance_function_with_1_state(self): """Test distance function with 1 state.""" self.hass.states.set('test.object', 'happy', {