We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add case-insensitive kwarg to the regex matcher
It would be nice to specify case insensitive matching in the regex matcher.

e.g
```python
@match_regex(r'myregex', case_sensitive=False)
async def myskill(opsdroid, config, message):
    pass
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opsdroid/parsers/regex.py`
Content:
```
1 """A helper function for parsing and executing regex skills."""
2 
3 import logging
4 import re
5 
6 
7 _LOGGER = logging.getLogger(__name__)
8 
9 
10 async def parse_regex(opsdroid, message):
11     """Parse a message against all regex skills."""
12     # pylint: disable=broad-except
13     # We want to catch all exceptions coming from a skill module and not
14     # halt the application. If a skill throws an exception it just doesn't
15     # give a response to the user, so an error response should be given.
16     for skill in opsdroid.skills:
17         if "regex" in skill:
18             regex = re.match(skill["regex"], message.text)
19             if regex:
20                 message.regex = regex
21                 try:
22                     await skill["skill"](opsdroid, skill["config"], message)
23                 except Exception:
24                     await message.respond(
25                         "Whoops there has been an error")
26                     await message.respond(
27                         "Check the log for details")
28                     _LOGGER.exception("Exception when parsing '" +
29                                       message.text +
30                                       "' against skill '" +
31                                       skill["regex"] + "'")
32
```

Path: `opsdroid/matchers.py`
Content:
```
1 """Decorator functions to use when creating skill modules."""
2 
3 import logging
4 
5 from opsdroid.helper import get_opsdroid
6 from opsdroid.web import Web
7 
8 
9 _LOGGER = logging.getLogger(__name__)
10 
11 
12 def match_regex(regex):
13     """Return regex match decorator."""
14     def matcher(func):
15         """Add decorated function to skills list for regex matching."""
16         opsdroid = get_opsdroid()
17         opsdroid.skills.append({"regex": regex, "skill": func,
18                                 "config":
19                                 opsdroid.loader.current_import_config})
20         return func
21     return matcher
22 
23 
24 def match_apiai_action(action):
25     """Return apiai action match decorator."""
26     def matcher(func):
27         """Add decorated function to skills list for apiai matching."""
28         opsdroid = get_opsdroid()
29         opsdroid.skills.append({"apiai_action": action, "skill": func,
30                                 "config":
31                                 opsdroid.loader.current_import_config})
32         return func
33     return matcher
34 
35 
36 def match_apiai_intent(intent):
37     """Return apiai intent match decorator."""
38     def matcher(func):
39         """Add decorated function to skills list for apiai matching."""
40         opsdroid = get_opsdroid()
41         opsdroid.skills.append({"apiai_intent": intent, "skill": func,
42                                 "config":
43                                 opsdroid.loader.current_import_config})
44         return func
45     return matcher
46 
47 
48 def match_crontab(crontab, timezone=None):
49     """Return crontab match decorator."""
50     def matcher(func):
51         """Add decorated function to skills list for crontab matching."""
52         opsdroid = get_opsdroid()
53         config = opsdroid.loader.current_import_config
54         opsdroid.skills.append({"crontab": crontab, "skill": func,
55                                 "config": config, "timezone": timezone})
56         return func
57     return matcher
58 
59 
60 def match_webhook(webhook):
61     """Return webhook match decorator."""
62     def matcher(func):
63         """Add decorated function to skills list for webhook matching."""
64         opsdroid = get_opsdroid()
65         config = opsdroid.loader.current_import_config
66         opsdroid.skills.append({"webhook": webhook, "skill": func,
67                                 "config": config})
68 
69         async def wrapper(req, opsdroid=opsdroid, config=config):
70             """Wrap up the aiohttp handler."""
71             _LOGGER.info("Running skill %s via webhook", webhook)
72             opsdroid.stats["webhooks_called"] = \
73                 opsdroid.stats["webhooks_called"] + 1
74             await func(opsdroid, config, req)
75             return Web.build_response(200, {"called_skill": webhook})
76 
77         opsdroid.web_server.web_app.router.add_post(
78             "/skill/{}/{}".format(config["name"], webhook), wrapper)
79         opsdroid.web_server.web_app.router.add_post(
80             "/skill/{}/{}/".format(config["name"], webhook), wrapper)
81 
82         return func
83     return matcher
84
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/opsdroid/matchers.py b/opsdroid/matchers.py
--- a/opsdroid/matchers.py
+++ b/opsdroid/matchers.py
@@ -9,12 +9,14 @@
 _LOGGER = logging.getLogger(__name__)
 
 
-def match_regex(regex):
+def match_regex(regex, case_sensitive=True):
     """Return regex match decorator."""
     def matcher(func):
         """Add decorated function to skills list for regex matching."""
         opsdroid = get_opsdroid()
-        opsdroid.skills.append({"regex": regex, "skill": func,
+        opsdroid.skills.append({"regex": {"expression": regex,
+                                          "case_sensitive": case_sensitive},
+                                "skill": func,
                                 "config":
                                 opsdroid.loader.current_import_config})
         return func
diff --git a/opsdroid/parsers/regex.py b/opsdroid/parsers/regex.py
--- a/opsdroid/parsers/regex.py
+++ b/opsdroid/parsers/regex.py
@@ -15,7 +15,12 @@
     # give a response to the user, so an error response should be given.
     for skill in opsdroid.skills:
         if "regex" in skill:
-            regex = re.match(skill["regex"], message.text)
+            if skill["regex"]["case_sensitive"]:
+                regex = re.match(skill["regex"]["expression"],
+                                 message.text)
+            else:
+                regex = re.match(skill["regex"]["expression"],
+                                 message.text, re.IGNORECASE)
             if regex:
                 message.regex = regex
                 try:
@@ -28,4 +33,4 @@
                     _LOGGER.exception("Exception when parsing '" +
                                       message.text +
                                       "' against skill '" +
-                                      skill["regex"] + "'")
+                                      skill["regex"]["expression"] + "'")

{"golden_diff": "diff --git a/opsdroid/matchers.py b/opsdroid/matchers.py\n--- a/opsdroid/matchers.py\n+++ b/opsdroid/matchers.py\n@@ -9,12 +9,14 @@\n _LOGGER = logging.getLogger(__name__)\n \n \n-def match_regex(regex):\n+def match_regex(regex, case_sensitive=True):\n     \"\"\"Return regex match decorator.\"\"\"\n     def matcher(func):\n         \"\"\"Add decorated function to skills list for regex matching.\"\"\"\n         opsdroid = get_opsdroid()\n-        opsdroid.skills.append({\"regex\": regex, \"skill\": func,\n+        opsdroid.skills.append({\"regex\": {\"expression\": regex,\n+                                          \"case_sensitive\": case_sensitive},\n+                                \"skill\": func,\n                                 \"config\":\n                                 opsdroid.loader.current_import_config})\n         return func\ndiff --git a/opsdroid/parsers/regex.py b/opsdroid/parsers/regex.py\n--- a/opsdroid/parsers/regex.py\n+++ b/opsdroid/parsers/regex.py\n@@ -15,7 +15,12 @@\n     # give a response to the user, so an error response should be given.\n     for skill in opsdroid.skills:\n         if \"regex\" in skill:\n-            regex = re.match(skill[\"regex\"], message.text)\n+            if skill[\"regex\"][\"case_sensitive\"]:\n+                regex = re.match(skill[\"regex\"][\"expression\"],\n+                                 message.text)\n+            else:\n+                regex = re.match(skill[\"regex\"][\"expression\"],\n+                                 message.text, re.IGNORECASE)\n             if regex:\n                 message.regex = regex\n                 try:\n@@ -28,4 +33,4 @@\n                     _LOGGER.exception(\"Exception when parsing '\" +\n                                       message.text +\n                                       \"' against skill '\" +\n-                                      skill[\"regex\"] + \"'\")\n+                                      skill[\"regex\"][\"expression\"] + \"'\")\n", "issue": "Add case-insensitive kwarg to the regex matcher\nIt would be nice to specify case insensitive matching in the regex matcher.\r\n\r\ne.g\r\n```python\r\n@match_regex(r'myregex', case_sensitive=False)\r\nasync def myskill(opsdroid, config, message):\r\n    pass\r\n```\n", "before_files": [{"content": "\"\"\"A helper function for parsing and executing regex skills.\"\"\"\n\nimport logging\nimport re\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\nasync def parse_regex(opsdroid, message):\n    \"\"\"Parse a message against all regex skills.\"\"\"\n    # pylint: disable=broad-except\n    # We want to catch all exceptions coming from a skill module and not\n    # halt the application. If a skill throws an exception it just doesn't\n    # give a response to the user, so an error response should be given.\n    for skill in opsdroid.skills:\n        if \"regex\" in skill:\n            regex = re.match(skill[\"regex\"], message.text)\n            if regex:\n                message.regex = regex\n                try:\n                    await skill[\"skill\"](opsdroid, skill[\"config\"], message)\n                except Exception:\n                    await message.respond(\n                        \"Whoops there has been an error\")\n                    await message.respond(\n                        \"Check the log for details\")\n                    _LOGGER.exception(\"Exception when parsing '\" +\n                                      message.text +\n                                      \"' against skill '\" +\n                                      skill[\"regex\"] + \"'\")\n", "path": "opsdroid/parsers/regex.py"}, {"content": "\"\"\"Decorator functions to use when creating skill modules.\"\"\"\n\nimport logging\n\nfrom opsdroid.helper import get_opsdroid\nfrom opsdroid.web import Web\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\ndef match_regex(regex):\n    \"\"\"Return regex match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for regex matching.\"\"\"\n        opsdroid = get_opsdroid()\n        opsdroid.skills.append({\"regex\": regex, \"skill\": func,\n                                \"config\":\n                                opsdroid.loader.current_import_config})\n        return func\n    return matcher\n\n\ndef match_apiai_action(action):\n    \"\"\"Return apiai action match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for apiai matching.\"\"\"\n        opsdroid = get_opsdroid()\n        opsdroid.skills.append({\"apiai_action\": action, \"skill\": func,\n                                \"config\":\n                                opsdroid.loader.current_import_config})\n        return func\n    return matcher\n\n\ndef match_apiai_intent(intent):\n    \"\"\"Return apiai intent match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for apiai matching.\"\"\"\n        opsdroid = get_opsdroid()\n        opsdroid.skills.append({\"apiai_intent\": intent, \"skill\": func,\n                                \"config\":\n                                opsdroid.loader.current_import_config})\n        return func\n    return matcher\n\n\ndef match_crontab(crontab, timezone=None):\n    \"\"\"Return crontab match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for crontab matching.\"\"\"\n        opsdroid = get_opsdroid()\n        config = opsdroid.loader.current_import_config\n        opsdroid.skills.append({\"crontab\": crontab, \"skill\": func,\n                                \"config\": config, \"timezone\": timezone})\n        return func\n    return matcher\n\n\ndef match_webhook(webhook):\n    \"\"\"Return webhook match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for webhook matching.\"\"\"\n        opsdroid = get_opsdroid()\n        config = opsdroid.loader.current_import_config\n        opsdroid.skills.append({\"webhook\": webhook, \"skill\": func,\n                                \"config\": config})\n\n        async def wrapper(req, opsdroid=opsdroid, config=config):\n            \"\"\"Wrap up the aiohttp handler.\"\"\"\n            _LOGGER.info(\"Running skill %s via webhook\", webhook)\n            opsdroid.stats[\"webhooks_called\"] = \\\n                opsdroid.stats[\"webhooks_called\"] + 1\n            await func(opsdroid, config, req)\n            return Web.build_response(200, {\"called_skill\": webhook})\n\n        opsdroid.web_server.web_app.router.add_post(\n            \"/skill/{}/{}\".format(config[\"name\"], webhook), wrapper)\n        opsdroid.web_server.web_app.router.add_post(\n            \"/skill/{}/{}/\".format(config[\"name\"], webhook), wrapper)\n\n        return func\n    return matcher\n", "path": "opsdroid/matchers.py"}], "after_files": [{"content": "\"\"\"A helper function for parsing and executing regex skills.\"\"\"\n\nimport logging\nimport re\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\nasync def parse_regex(opsdroid, message):\n    \"\"\"Parse a message against all regex skills.\"\"\"\n    # pylint: disable=broad-except\n    # We want to catch all exceptions coming from a skill module and not\n    # halt the application. If a skill throws an exception it just doesn't\n    # give a response to the user, so an error response should be given.\n    for skill in opsdroid.skills:\n        if \"regex\" in skill:\n            if skill[\"regex\"][\"case_sensitive\"]:\n                regex = re.match(skill[\"regex\"][\"expression\"],\n                                 message.text)\n            else:\n                regex = re.match(skill[\"regex\"][\"expression\"],\n                                 message.text, re.IGNORECASE)\n            if regex:\n                message.regex = regex\n                try:\n                    await skill[\"skill\"](opsdroid, skill[\"config\"], message)\n                except Exception:\n                    await message.respond(\n                        \"Whoops there has been an error\")\n                    await message.respond(\n                        \"Check the log for details\")\n                    _LOGGER.exception(\"Exception when parsing '\" +\n                                      message.text +\n                                      \"' against skill '\" +\n                                      skill[\"regex\"][\"expression\"] + \"'\")\n", "path": "opsdroid/parsers/regex.py"}, {"content": "\"\"\"Decorator functions to use when creating skill modules.\"\"\"\n\nimport logging\n\nfrom opsdroid.helper import get_opsdroid\nfrom opsdroid.web import Web\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\ndef match_regex(regex, case_sensitive=True):\n    \"\"\"Return regex match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for regex matching.\"\"\"\n        opsdroid = get_opsdroid()\n        opsdroid.skills.append({\"regex\": {\"expression\": regex,\n                                          \"case_sensitive\": case_sensitive},\n                                \"skill\": func,\n                                \"config\":\n                                opsdroid.loader.current_import_config})\n        return func\n    return matcher\n\n\ndef match_apiai_action(action):\n    \"\"\"Return apiai action match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for apiai matching.\"\"\"\n        opsdroid = get_opsdroid()\n        opsdroid.skills.append({\"apiai_action\": action, \"skill\": func,\n                                \"config\":\n                                opsdroid.loader.current_import_config})\n        return func\n    return matcher\n\n\ndef match_apiai_intent(intent):\n    \"\"\"Return apiai intent match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for apiai matching.\"\"\"\n        opsdroid = get_opsdroid()\n        opsdroid.skills.append({\"apiai_intent\": intent, \"skill\": func,\n                                \"config\":\n                                opsdroid.loader.current_import_config})\n        return func\n    return matcher\n\n\ndef match_crontab(crontab, timezone=None):\n    \"\"\"Return crontab match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for crontab matching.\"\"\"\n        opsdroid = get_opsdroid()\n        config = opsdroid.loader.current_import_config\n        opsdroid.skills.append({\"crontab\": crontab, \"skill\": func,\n                                \"config\": config, \"timezone\": timezone})\n        return func\n    return matcher\n\n\ndef match_webhook(webhook):\n    \"\"\"Return webhook match decorator.\"\"\"\n    def matcher(func):\n        \"\"\"Add decorated function to skills list for webhook matching.\"\"\"\n        opsdroid = get_opsdroid()\n        config = opsdroid.loader.current_import_config\n        opsdroid.skills.append({\"webhook\": webhook, \"skill\": func,\n                                \"config\": config})\n\n        async def wrapper(req, opsdroid=opsdroid, config=config):\n            \"\"\"Wrap up the aiohttp handler.\"\"\"\n            _LOGGER.info(\"Running skill %s via webhook\", webhook)\n            opsdroid.stats[\"webhooks_called\"] = \\\n                opsdroid.stats[\"webhooks_called\"] + 1\n            await func(opsdroid, config, req)\n            return Web.build_response(200, {\"called_skill\": webhook})\n\n        opsdroid.web_server.web_app.router.add_post(\n            \"/skill/{}/{}\".format(config[\"name\"], webhook), wrapper)\n        opsdroid.web_server.web_app.router.add_post(\n            \"/skill/{}/{}/\".format(config[\"name\"], webhook), wrapper)\n\n        return func\n    return matcher\n", "path": "opsdroid/matchers.py"}]}