Python Forum
Help getting a string out of regex - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Help getting a string out of regex (/thread-31274.html)



Help getting a string out of regex - matt_the_hall - Dec-01-2020

Hello, I am trying to better understand the regular expression module, specifically, how to get it to return a string that I can use elsewhere.

Preface to the code:

This is a script for an open source chat server called "Zulip," utilizing their API. The script is working fine until I get a "not None" response, and then I get the following error:

Error:
unning Snoozebot Bot: The goal here is to have a snooze for messages, similar to the snooze function on Gmail. When you write @snoozebot a message for a snooze reminder x minutes, hours, days, etc. from now @snoozebot first replies by echoing back the requested snooze time interval. X time later, it sends a message to the stream pinging the users in the snooze request. I am thinking of something like @snoozebot snooze for (x) (time) for [list of users]. INFO:root:starting message handling... INFO:root:waiting for next message Traceback (most recent call last): File "/home/zulip/.local/bin/zulip-run-bot", line 10, in <module> sys.exit(main()) File "/home/zulip/.local/lib/python3.7/site-packages/zulip_bots/run.py", line 152, in main bot_name=bot_name File "/home/zulip/.local/lib/python3.7/site-packages/zulip_bots/lib.py", line 382, in run_message_handler_for_bot client.call_on_each_event(event_callback, ['message']) File "/usr/local/lib/python3.7/dist-packages/zulip/__init__.py", line 680, in call_on_each_event callback(event) File "/home/zulip/.local/lib/python3.7/site-packages/zulip_bots/lib.py", line 380, in event_callback handle_message(event['message'], event['flags']) File "/home/zulip/.local/lib/python3.7/site-packages/zulip_bots/lib.py", line 371, in handle_message bot_handler=restricted_client File "/home/zulip/python-zulip-api/zulip_bots/zulip_bots/bots/snoozebot/snoozebot.py", line 31, in handle_message match.join(y) AttributeError: 'list' object has no attribute 'join'
Is my syntax/understanding wrong for how to utilize the join method? I was thinking that match = the string I want, y = the list containing the base string I want to append to, so match.join(y) should join match to the list in y. Or, am I still not getting a string out of regex that can be appended to a list?


Here's the script:


from typing import Any, Dict
import  re

class SnoozeBotHandler:


    def usage(self) -> str:
        return '''
        The goal here is to have a snooze for messages, similar to the snooze function on Gmail. When you write
        @snoozebot a message for a snooze reminder x minutes, hours, days, etc. from now @snoozebot
        first replies by echoing back the requested snooze time interval. X time later, it sends a message to the
        stream pinging the users in the snooze request. I am thinking of something like @snoozebot snooze for (x) (time)
        for [list of users].
        '''

    def handle_message(self, message: Dict[str, Any], bot_handler: Any) -> None:
        # setting up regex pattern here
        # hopefully this pattern object will work for any iteration of "snooze for x days/weeks/months...will have to test.
        pattern1 = re.compile(r'(\bday\b)', re.IGNORECASE)
        match = pattern1.findall(message['content'])
        # message handling
        if message['content'] == '':
            bot_response = "Please specify the **snooze interval** and **users** to be reminded. For help, message me with 'help.'"
            bot_handler.send_reply(message, bot_response)
        elif message['content'] == 'help':
            bot_handler.send_reply(message, self.usage())
        else:
            if pattern1.search(message['content']) != None:
                
                y = ["Ok, I'll remind you in "]
                match.join(y)
                bot_handler.send_reply(message, y)
                emoji_name = 'alarm clock'
                bot_handler.react(message, emoji_name)
            else:
                bot_handler.send_reply(message, "Oops, that won't work. Message me with 'help' for help on how to use me.")
        return

handler_class = SnoozeBotHandler



RE: Help getting a string out of regex - bowlofred - Dec-01-2020

You don't join things into a list. If you have one element you want to add, you .append() it. If you have another list you want to tack onto the end you .extend() it.

re.findall should return a list (of possibly identical items), so extending is I guess what you want...

match = ["match1", "match2"]
y = ["item1"]
y.extend(match)
print(y)
Output:
['item1', 'match1', 'match2']



RE: Help getting a string out of regex - matt_the_hall - Dec-01-2020

@bowlofred, Thanks so much, that did get me closer to what I am aiming for. I am, however, trying to get a final output that is all one string, like this: Ok, I'll remind you in 4 days. I haven't set up the regular expression to take # day(s), yet; I am just using 'day' for simplicity's sake.

In any case, perhaps you can help me understand the output I am getting, now. Below is the raw output in the terminal (using print functions to try and help me understand what my code is doing):

Error:
INFO:root:starting message handling... INFO:root:waiting for next message day ['day'] Ok, I'll remind you in INFO:root:waiting for next message
And here's the updated code:

              y = "Ok, I'll remind you in "
                x = str(match[0])
                print(x)
                print(match)
                y.join(x)
                print(y)
                bot_handler.send_reply(message, y)
So, I'm a little confused why y.join(x) is not tacking 'day' onto the end of 'Ok, I'll remind you in '. Am I correct in understanding that x = str(match[0]) converts the 0th element of the list match to a string object equal to x? if so, why do I get 'Ok, I'll remind you in ' for print(y)?


RE: Help getting a string out of regex - bowlofred - Dec-01-2020

join() is an operator on a string, and it doesn't modify anything. It returns a new string.

Since you're not assigning the result of the join, the result is thrown away and y remains the same.

y = "Hello, world!"
l = ["one", "two", "three"]
y.join(l)
print(y)  # no change

y = y.join(l) # assigns the change back to y
print(y)    # now the change is seen
Output:
Hello, world! oneHello, world!twoHello, world!three
That said, I'm not sure you want to join() at all. It sounds like you just want to concatenate two strings. You can do that with a plus symbol if you have two strings.


RE: Help getting a string out of regex - matt_the_hall - Dec-02-2020

It works! Thank you so much! Gosh, I read so many tutorials and threads on this, and no one explained it so simply and clearly. Would you mind suggesting a book or two that you think might help me progress in my Python skills?