1

I am trying to extract numbers from a string. Without any fancy inports like regex and for or if statements.

Example 495 * 89

Output 495 89

Edit I have tried this:

num1 = int(''.join(filter(str.isdigit, num)))

It works, but doesn't space out the numbers

1
  • You could use a simple state machine that reads characters, accumulating digits. When it hits a non-digit or EOF, that accumulated string is the next number. Commented Oct 7, 2021 at 23:36

3 Answers 3

2

Actually, regex is a very simple and viable option here:

inp = "495   *  89"
nums = re.findall(r'\d+(?:\.\d+)?', inp)
print(nums)  # ['495', '89']

Assuming you always expect integers and you want to avoid regex, you could use a string split approach with a list comprehension:

inp = "495   *  89"
parts = inp.split()
nums = [x for x in parts if x.isdigit()]
print(nums)  # ['495', '89']
Sign up to request clarification or add additional context in comments.

2 Comments

is there any way to do it without regex?
Yes, you could avoid regex in some cases.
1

You can do this without much fancy stuff

s = "495   *  89"

#replace non-digits with spaces, goes into a list of characters
li = [c if c.isdigit() else " " for c in s ]

#join characters back into a string
s_digit_spaces = "".join(li)

#split will separate on space boundaries, multiple spaces count as one
nums = s_digit_spaces.split()

print(nums)

#one-liner:
print ("".join([c if c.isdigit() else " " for c in s ]).split())

output:

['495', '89']
['495', '89']
#and with non-digit number stuff
s = "495.1   *  -89"
print ("".join([c if (c.isdigit() or c in ('-',".")) else " " for c in s ]).split())

output:

['495.1', '-89']

Finally, this works too:

print ("".join([c if c in  "0123456789+-." else " " for c in s ]).split())

2 Comments

A thing to note here is the function, isdigit(), only gets numbers and ignores things like negative signs and decimals, ending with unexpected results (e.g. 3.5 -> 35 or 3 5), however that should be easy to fix if needed. Upvoted nevertheless.
@ZaidAlShattle great minds think alike ;-)
1

You're close.

You don't want to int() a single value when there are multiple numbers in the string. The filter function is being applied over characters, since strings are iterable that way

Instead, you need to first split the string into its individual tokens, then filter whole numerical strings, then cast each element

s = "123 * 54"
digits = list(map(int, filter(str.isdigit, s.split()))) 

Keep in mind, this only handles non-negative integers

4 Comments

Thank You so much you're a lifesaver.
The regex find_all would be faster, though
@OneCricketeer A side question, if you may, would regex be faster in most cases, or is it more specific to this? I am honestly curious and will try to run a few tests with different methods for this case.
@Zaid I'd guess almost all cases since it wouldn't require splitting, and parsing the input twice

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.