Thread overview
User input parsing
Oct 14, 2015
Joel
Oct 14, 2015
Andrea Fontana
Oct 14, 2015
Ali Çehreli
Oct 14, 2015
Joel
October 14, 2015
Is there a fast way to get a number out of a text input?

Like getting '1.5' out of 'sdaz1.5;['.

Here's what I have at the moment:
			string processValue(string s) {
				string ns;
				foreach(c; s) {
					if (c >= '0' && c <= '9')
						ns ~= c;
					else if (c == '.')
						ns ~= '.';
				}

				return ns;
			}

October 14, 2015
On Wednesday, 14 October 2015 at 07:14:45 UTC, Joel wrote:
> Is there a fast way to get a number out of a text input?
>
> Like getting '1.5' out of 'sdaz1.5;['.
>
> Here's what I have at the moment:
> 			string processValue(string s) {
> 				string ns;
> 				foreach(c; s) {
> 					if (c >= '0' && c <= '9')
> 						ns ~= c;
> 					else if (c == '.')
> 						ns ~= '.';
> 				}
>
> 				return ns;
> 			}

What about "sdaz1.a3..44["?

Anyway, you could use an appender, or reserve memory to speed up your code.
October 14, 2015
On 10/14/2015 12:14 AM, Joel wrote:
> Is there a fast way to get a number out of a text input?
>
> Like getting '1.5' out of 'sdaz1.5;['.
>
> Here's what I have at the moment:
>              string processValue(string s) {
>                  string ns;
>                  foreach(c; s) {
>                      if (c >= '0' && c <= '9')
>                          ns ~= c;
>                      else if (c == '.')
>                          ns ~= '.';
>                  }
>
>                  return ns;
>              }
>

Regular expressions:

import std.stdio;
import std.regex;

void main() {
    auto input = "sdaz1.5;[";
    auto pattern = ctRegex!(`([^-0-9.]*)([-0-9.]+)(.*)`);
    auto m = input.matchFirst(pattern);

    if (m)  {
        assert(m[0] == "sdaz1.5;[");    // whole
        assert(m[1] == "sdaz");         // before
        assert(m[2] == "1.5");          // number
        assert(m[3] == ";[");           // after
    }
}

1) I am not good with regular expressions. So, the floating point selector [-0-9.]+ is very primitive. I recommend that you search for a better one. :)

2) ctRegex is slow to compile. Replace ctRegex!(expr) with regex(expr) for faster compilations and slower execution (probably unnoticeably slow in most cases).

3) If you want to extract a number out of a constant string, formattedRead (or readf) can be used as well:

import std.stdio;
import std.format;

void main() {
    auto input = "Distance: 1.5 feet";
    double number;

    const quantity = formattedRead(input, "Distance: %f feet", &number);
    assert(number == 1.5);
}

Ali

October 14, 2015
Thanks guys. I did think of regex, but I don't know how to learn it.