1

Apparently I still don't understand exactly how it works ...

Here is my problem: I'm trying to match numbers in strings such as:

     910     -6.258000  6.290

That string should gives me an array like this:

[910, -6.2580000, 6.290]

while the string

  blabla9999 some more text 1.1

should not be matched.

The regex I'm trying to use is

/([-]?\d+[.]?\d+)/

but it doesn't do exactly that. Could someone help me ?

It would be great if the answer could clarify the use of the parenthesis in the matching.

1
  • 3
    Have you considered splitting on whitespace instead? Commented Sep 12, 2011 at 12:41

4 Answers 4

2

Here's a pattern that works:

/^[^\d]+?\d+[^\d]+?\d+[\.]?\d+$/

Note that [^\d]+ means at least one non digit character.

On second thought, here's a more generic solution that doesn't need to deal with regular expressions:

str.gsub(/[^\d.-]+/, " ").split.collect{|d| d.to_f}

Example:

str = "blabla9999 some more text -1.1"

Parsed:

[9999.0, -1.1]
Sign up to request clarification or add additional context in comments.

Comments

2

The parenthesis have different meanings.

[] defines a character class, that means one character is matched that is part of this class

() is defining a capturing group, the string that is matched by this part in brackets is put into a variable.

You did not define any anchors so your pattern will match your second string

blabla9999 some more text 1.1
      ^^^^  here          ^^^ and here

Maybe this is more what you wanted

^(\s*-?\d+(?:\.\d+)?\s*)+$

See it here on Regexr

^ anchors the pattern to the start of the string and $ to the end.

it allows Whitespace \s before and after the number and an optional fraction part (?:\.\d+)? This kind of pattern will be matched at least once.

2 Comments

"You did not define any anchors": what do you mean by anchor ?
@Cedric an anchor anchors the pattern to certain points, like the start of the string or of a word. without it you allow your pattern starting to match directly after your letters.
2

maybe /(-?\d+(.\d+)?)+/

irb(main):010:0> "910     -6.258000  6.290".scan(/(\-?\d+(\.\d+)?)+/).map{|x| x[0]}
=> ["910", "-6.258000", "6.290"]

Comments

0
str = "    910     -6.258000  6.290"
str.scan(/-?\d+\.?\d+/).map(&:to_f)
# => [910.0, -6.258, 6.29]

If you don't want integers to be converted to floats, try this:

str = "    910     -6.258000  6.290"
str.scan(/-?\d+\.?\d+/).map do |ns|
  ns[/\./] ? ns.to_f : ns.to_i
end
# => [910, -6.258, 6.29]

Comments

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.