#๐ i want it to print like if there was no group here how to
143 messages ยท Page 1 of 1 (latest)
@mortal swan
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
Closes after a period of inactivity, or when you send !close.
Hey @mortal swan!
Please edit your message to use a code block
Make sure you put your code on a new line following py. There must not be any spaces after py.
Here is an example of how it should look:
```py
print('Hello, world!')
```
This will result in the following:
print('Hello, world!')```
py
import pyperclip, re
phoneRegex = re.compile((r'([0-9]{3}|(\[0-9])\{3})?(\s|-|\.)?([0-9]{3})(\s|-|\.)?([0-9]{3})(\s|-|\.)?([0-9]{4})'))
mo=phoneRegex.findall(r"(324)-243-234-2423 is a good number not readllly (334)-253-264-2422)")
print(mo)
code
i dont want it return me tuples basically
can you paste the code here instead of a screenshot?
this
i want like how they are in text that way neat
yeah
and not like tuples
!e
import re
phoneRegex = re.compile((r'([0-9]{3}|(\[0-9])\{3})?(\s|-|\.)?([0-9]{3})(\s|-|\.)?([0-9]{3})(\s|-|\.)?([0-9]{4})'))
#mo=phoneRegex.findall(r"(324)-243-234-2423 is a good number not readllly (334)-253-264-2422)")
mo=phoneRegex.search(r"(324)-243-234-2423 is a good number not readllly (334)-253-264-2422)")
print(mo.group())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
-243-234-2423
it didnt included area code
neither did your findall
oh wait
the \ will always come first
(324)-243-234-2423
this also isn't a valid number
it should be 3 digits for area code
then 3 more, then 4
(123)-456-7890
it returned none now
let's back up and rebuild so that it makes sense
!e
import re
phoneRegex = re.compile(r'\([0-9]{3}\)-[0-9]{3}-[0-9]{4}')
mo=phoneRegex.search(r"(243)-234-2423 is a good number not readllly (334)-264-2422)")
print(mo.group())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
(243)-234-2423
here's a regex for 3 digits in (), followed by -, then 3 digits, then -, then 4 digits
ok now let's add the or back in. I'm also going to change search to re.finditer so we can loop through all matches
!e
import re
phoneRegex = re.compile(r'([0-9]{3}|\([0-9]{3}\))-[0-9]{3}-[0-9]{4}')
matches = phoneRegex.finditer(r"(243)-234-2423 is a good number not readllly 334-264-2422)")
for match in matches:
print(match.group())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | (243)-234-2423
002 | 334-264-2422
now we're matching with and without () for the area code
but ig u forgot ? to set area code optional
You're right
we can add the ? after the group now, but we'll run into the issue of the - after the area code
so we can create a nested group here for the separator
!e
import re
phoneRegex = re.compile(r'(([0-9]{3}|\([0-9]{3}\))?(-)?)[0-9]{3}-[0-9]{4}')
matches = phoneRegex.finditer(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
for match in matches:
print(match.group())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | (243)-234-2423
002 | 334-264-2422
003 | 123-4567
basically now we're saying "if there's an area code, capture it and its separator"
ok now we can add groups for our other digits
if we use the groups() method, we can start to view all the groups we're capturing
!e
import re
phoneRegex = re.compile(r'([0-9]{3}|\([0-9]{3}\))?(-)?([0-9]{3})-([0-9]{4})')
matches = phoneRegex.finditer(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
for match in matches:
print(match.groups())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | ('(243)', '-', '234', '2423')
002 | ('334', '-', '264', '2422')
003 | (None, None, '123', '4567')
the 3rd line here tells us there was no area code
!e
import re
phoneRegex = re.compile(r'(([0-9]{3}|\([0-9]{3}\))?(-)?)[0-9]{3}-[0-9]{4}')
matches = phoneRegex.search(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
print(matches.group())
:warning: Your 3.12 eval job has completed with return code 0.
[No output]
why this
!e
import re
phoneRegex = re.compile(r'(([0-9]{3}|\([0-9]{3}\))?(-)?)[0-9]{3}-[0-9]{4}')
matches = phoneRegex.search(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
print(matches.groups())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
(243)-234-2423
if we want a specific group, we can index it
matches.group(1) would give us the first group
or, we can do .groups() to see all the returned groups at once
!e
import re
phoneRegex = re.compile(r'(([0-9]{3}|\([0-9]{3}\))?(-)?)[0-9]{3}-[0-9]{4}')
matches = phoneRegex.search(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
print(matches.groups())
:white_check_mark: Your 3.12 eval job has completed with return code 0.
('(243)-', '(243)', '-')
import re
phoneRegex = re.compile(r'([0-9]{3}|\([0-9]{3}\))?(-)?([0-9]{3})-([0-9]{4})')
matches = phoneRegex.finditer(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
for match in matches:
area_code, sep1, first_3, last_4 = match.groups()
it can be really useful when you do multiple assignment like this
then we end up with variables for each of the groups
isnt match.group a string?
yes
then how can u assign multiple variable its in list?
oh yeah
!e
import re
phoneRegex = re.compile(r'([0-9]{3}|\([0-9]{3}\))?(-)?([0-9]{3})-([0-9]{4})')
matches = phoneRegex.finditer(r"(243)-234-2423 is a good number not readllly 334-264-2422 but also 123-4567")
for match in matches:
area_code, sep1, first_3, last_4 = match.groups()
if area_code:
print(f"The area code is {area_code}")
else:
print("No area code")
print(f"The first 3 digits are {first_3}")
print(f"The last 4 digits are {last_4}")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | The area code is (243)
002 | The first 3 digits are 234
003 | The last 4 digits are 2423
004 | The area code is 334
005 | The first 3 digits are 264
006 | The last 4 digits are 2422
007 | No area code
008 | The first 3 digits are 123
009 | The last 4 digits are 4567
then you can do neat things like this
cool
if there's an area code, display it, then display the remaining digit groups
in my example I only used - as the separator
but now it's fairly trivial to go update it with your other separator options
I like keeping them simple in the beginning until I can confirm they work, then I'll increase their complexity as I keep testing
instead of trying to write one mega beast of a regex from the start
this is how you should approach coding in general
keep it simple, test often, then build on that
if there was no match, then mo will be None
it's common to include if mo:
only proceed if a match was found
oh
that's why finditer worked ok in my example. If there was no match, then matches would be empty
but why its not matching
how to do it with search and whats difference between itr and search?
search only returns the first match in the string
if you have many phone numbers in a string and you want all of them, then you don't want search
findall returns a string of all matches
finditer returns an iterable of match objects
cool it worked ig so when using for loop i have to use iter?
findall returns a list of matches. finditer is a generator and yields the matches. Both are "iterable". A for-loop iterates over what you give it, which must be iterable.
So for match in findall(...): and for match in finditer(.....): will behave similarly.
ok
So findall finds all the matches and collects them all in a list and returns that. So it does all the work before the for-loop gets any data.
finditer yields a match one at a time. The for loop can start working as soon as the first match is found.
Foro small amounts of text the difference is negligible.
But for big things and open ended things (no finish) you often want to get an iterable, giving you answers as produced.
find all did nothing
For example, imagine a function primes() yielding the primes. There's an infinite number of primes. Can't compute all of them first.
You're literally searching the text:
pyperclip.paste()
and not whatever calling pyperclip.paste() would have returned.
oh wait
sorry was away, I'm back now
it worked so whts the difference
one just collects first and second as we go is there differnce in functionality?
"pyperclip.paste()" and pyperclip.paste() are very different
yeah ik
so what "difference" are you asking about?
i meant findall and finditer
they mentioned a "generator", which is a form of iterable in python
and their example of prime numbers was great. You couldn't have a function that says "Get me all the prime numbers", because that is endless
but you could have a function that says "get me the next prime number"
finditer works in a similar way
it basically performs re.search until it finds a match, and then it basically pauses its searching there
tyvm gotcha
and then you can ask it for the next one, and it will resume searching until it finds another one (or reaches the end of the string)
import re
text = 'a2bc15d9e'
matches = re.finditer('[a-z]', text)
have a look at this basic example
it finds all single letters inside this string
generators can make use of a special function called next()
I don't have to use a for loop, but instead I could just say "what's the first match"
!e
import re
text = 'a2bc15d9e'
matches = re.finditer('[a-z]', text)
print(next(matches))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
<re.Match object; span=(0, 1), match='a'>
if I wanted the first 3 matches, I could call next() 3 times
!e
import re
text = 'a2bc15d9e'
matches = re.finditer('[a-z]', text)
print(next(matches))
print(next(matches))
print(next(matches))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | <re.Match object; span=(0, 1), match='a'>
002 | <re.Match object; span=(2, 3), match='b'>
003 | <re.Match object; span=(3, 4), match='c'>
!e
import re
text = 'a2bc15d9e'
matches = re.finditer('[a-z]', text)
print(next(matches))
print(next(matches))
print(next(matches))
print(next(matches))
print(next(matches))
print(next(matches))
:x: Your 3.12 eval job has completed with return code 1.
001 | <re.Match object; span=(0, 1), match='a'>
002 | <re.Match object; span=(2, 3), match='b'>
003 | <re.Match object; span=(3, 4), match='c'>
004 | <re.Match object; span=(6, 7), match='d'>
005 | <re.Match object; span=(8, 9), match='e'>
006 | Traceback (most recent call last):
007 | File "/home/main.py", line 13, in <module>
008 | print(next(matches))
009 | ^^^^^^^^^^^^^
010 | StopIteration
look what happens if I call next() too many times
there were only 5 matches, but I did next() 6 times
This is actually how for loops work under the hood
it basically calls next() over and over until it reaches a StopIteration error, then it knows to stop
This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.