Python Forum
Help getting a string out of regex
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help getting a string out of regex
#1
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
Reply
#2
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']
Reply
#3
@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)?
Reply
#4
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.
Reply
#5
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?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Regex: a string does not starts and ends with the same character Melcu54 5 2,367 Jul-04-2021, 07:51 PM
Last Post: Melcu54
  Please support regex for version number (digits and dots) from a string Tecuma 4 3,102 Aug-17-2020, 09:59 AM
Last Post: Tecuma
  regex match in a string batchen 4 3,160 Jan-20-2020, 08:48 AM
Last Post: batchen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020