Asked  7 Months ago    Answers:  5   Viewed   38 times

I have a String variable (basically an English sentence with an unspecified number of numbers) and I'd like to extract all the numbers into an array of integers. I was wondering whether there was a quick solution with regular expressions?


I used Sean's solution and changed it slightly:

LinkedList<String> numbers = new LinkedList<String>();

Pattern p = Pattern.compile("\d+");
Matcher m = p.matcher(line); 
while (m.find()) {
   numbers.add(m.group());
}

 Answers

83
Pattern p = Pattern.compile("-?\d+");
Matcher m = p.matcher("There are more than -2 and less than 12 numbers here");
while (m.find()) {
  System.out.println(m.group());
}

... prints -2 and 12.


-? matches a leading negative sign -- optionally. d matches a digit, and we need to write as \ in a Java String though. So, d+ matches 1 or more digits.

Tuesday, June 1, 2021
 
penpen
answered 7 Months ago
68

If you only want to extract only positive integers, try the following:

>>> txt = "h3110 23 cat 444.4 rabbit 11 2 dog"
>>> [int(s) for s in txt.split() if s.isdigit()]
[23, 11, 2]

I would argue that this is better than the regex example because you don't need another module and it's more readable because you don't need to parse (and learn) the regex mini-language.

This will not recognize floats, negative integers, or integers in hexadecimal format. If you can't accept these limitations, jmnas's answer below will do the trick.

Tuesday, June 1, 2021
 
letrollpoilu
answered 7 Months ago
32

filter works, but you need the right predicate function, which Boolean isn't (for this purpose):

// Example 1 - Using String#trim (added in ES2015, needs polyfilling in outdated
// environments like IE)
arr = arr.filter(function(entry) { return entry.trim() != ''; });

or

// Example 2 - Using a regular expression instead of String#trim
arr = arr.filter(function(entry) { return /S/.test(entry); });

(S means "a non-whitespace character," so /S/.test(...) checks if a string contains at least one non-whitespace char.)

or (perhaps a bit overboard and harder to read)

// Example 3
var rex = /S/;
arr = arr.filter(rex.test.bind(rex));

With an ES2015 (aka ES6) arrow function, that's even more concise:

// Example 4
arr = arr.filter(entry => entry.trim() != '');

or

// Example 5
arr = arr.filter(entry => /S/.test(entry));

Live Examples -- The ES5 and earlier ones:

var arr = ['Apple', '  ', 'Mango', '', 'Banana', ' ', 'Strawberry'];
console.log("Example 1: " + JSON.stringify(arr.filter(function(entry) { return entry.trim() != ''; })));
console.log("Example 2: " + JSON.stringify(arr.filter(function(entry) { return /S/.test(entry); })));
var rex = /S/;
console.log("Example 3: " + JSON.stringify(arr.filter(rex.test.bind(rex))));

...and the ES2015 (ES6) ones (won't work if your browser doesn't support arrow functions yet):

var arr = ['Apple', '  ', 'Mango', '', 'Banana', ' ', 'Strawberry'];
console.log("Example 4: " + JSON.stringify(arr.filter(entry => !entry.trim() == '')));
console.log("Example 5: " + JSON.stringify(arr.filter(entry => /S/.test(entry))));
Monday, August 2, 2021
 
BrunoRamalho
answered 5 Months ago
29

I think you need to process each item in the list as a split string on whitespace.

a = ['1 2 3', '4 5 6', 'invalid']
numbers = []
for item in a:
    for subitem in item.split():
        if(subitem.isdigit()):
            numbers.append(subitem)
print(numbers)

['1', '2', '3', '4', '5', '6']

Or in a neat and tidy comprehension:

[item for subitem in a for item in subitem.split() if item.isdigit()]
Monday, November 22, 2021
 
Arseny Istlentyev
answered 2 Weeks ago
37

You could treat it as part of a JSON string and append the necessary parts for parsing as array.

var string ='"long one","short","oh, look","wow.", ""',
    array = JSON.parse('[' + string + ']');
console.log(array);
Saturday, December 4, 2021
 
Timur Mustafaev
answered 2 Days ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share