3

I'm working with a DNN form-building module that allows for some server-side code to be run based on a condition. For my particular scenario, I need my block of code to run if the first 4 characters of a certain form text are numeric.

The space to type the condition, though, is only one line and I believe gets injected into an if statement somewhere behind the scenes so I don't have the ability to write a mult-line conditional.

If I have a form field called MyField, I might create a simple conditional like this:

[MyField] == "some value"

Then somewhere behind the scenes it gets translated to something like if("some value" == "some value") {

I know that int.TryParse() can be used to determine whether or not a string is numeric but every implementation I've seen requires two lines of code, the first to declare a variable to contain the converted integer and the second to run the actual function.

Is there a way to check to see if the first 4 characters of a string are numeric in just one line that can exist inside an if statement?

TheIronCheek
  • 1,077
  • 2
  • 20
  • 50

3 Answers3

11

Wrap it in an extension method.

public static class StringExtensions
{
    public static bool IsNumeric(this string input)
    {
        int number;
        return int.TryParse(input, out number);
    }
}

And use it like

if("1234".IsNumeric())
{
    // Do stuff..
}

UPDATE since question changed:

public static class StringExtensions
{
    public static bool FirstFourAreNumeric(this string input)
    {
        int number;
        if(string.IsNullOrEmpty(input) || input.Length < 4)
        {
            throw new Exception("Not 4 chars long");
        }

        return int.TryParse(input.Substring(4), out number);
    }
}

And use it like

if("1234abc".FirstFourAreNumeric())
{
    // Do stuff..
}
smoksnes
  • 10,509
  • 4
  • 49
  • 74
  • 1
    Doesn't handle long numeric numbers, nor does it handle comma/period delimiters. – AgentFire Aug 08 '16 at 14:04
  • This answers the question, but using `@this` as a parameter name is a very, very bad choice. Not to mention using it as an extension method parameter. Personally i find using keywords as parameter and variable names as something to be avoided. – Zein Makki Aug 08 '16 at 14:04
  • @user3185569 - You might be right regarding the parameter name. I changed it to `input`. Personally I find `@this` very logical in this (pun not intended) particular case just because it shows what your extension is extending. But that's just me. – smoksnes Aug 08 '16 at 14:09
  • @AgentFire - Yes, in that case you might want to use `Int64.TryParse`, but I understood the OP as `int.TryParse` could be used, but not in a single line. – smoksnes Aug 08 '16 at 14:11
  • return int.TryParse(input, out int number); saves 1 line. – Roni Tovi Dec 18 '17 at 17:05
  • This is great, since I'm only iterating through one character at a time in a string, and I need to check if that character is a number. Thanks! – Momoro Jun 06 '21 at 23:22
4

In response to this:

Is there a way to check to see if the first 4 characters of a string are numeric in just one line that can exist inside an if statement?

You guys don't have to make it account for anything more complicated than a positive integer.

new Regex(@"^\d{4}").IsMatch("3466") // true
new Regex(@"^\d{4}").IsMatch("6")    // false
new Regex(@"^\d{4}").IsMatch("68ab") // false
new Regex(@"^\d{4}").IsMatch("1111abcdefg") // true

// in an if:
if (new Regex(@"^\d{4}").IsMatch("3466"))
{
    // Do something
}

Old answer:

If you can't use TryParse, you could probably get away with using LINQ:

"12345".All(char.IsDigit); // true
"abcde".All(char.IsDigit); // false
"abc123".All(char.IsDigit); // false

If you can, here's an IsNumeric extension method, with usage:

public static class NumberExtensions
{
    // <= C#6
    public static bool IsNumeric(this string str)
    {
        float f;
        return float.TryParse(str, out f);
    }

    // C# 7+
    public static bool IsNumeric(this string str) => float.TryParse(str, out var _);
}

// ... elsewhere

"123".IsNumeric();     // true
"abc".IsNumeric();     // false, etc
"-1.7e5".IsNumeric();  // true
Community
  • 1
  • 1
Scott
  • 5,338
  • 5
  • 45
  • 70
  • 1
    problem is this doesn't !00% verify it's an `int` – Jonesopolis Aug 08 '16 at 13:57
  • @Jonesopolis True, it's a workaround for sure. The extension method approach is better, but if OP is just after a basic "string only contains numbers" method, it should work. – Scott Aug 08 '16 at 14:01
  • @AgentFire Neither does `int.TryParse`. I'll update to use `float.TryParse` for the extension method. This problem could be solved in a lot of ways (including regex), the "best" solution just depends on what the OP needs. – Scott Aug 08 '16 at 14:06
  • You guys don't have to make it account for anything more complicated than a positive integer. I'll update the question to be more specific about this. – TheIronCheek Aug 08 '16 at 14:13
  • "".All(char.IsDigit); returns "TRUE" – M. Fawad Surosh Sep 28 '17 at 19:01
  • @M.FawadSurosh Personally I would handle that as a different validation case. For example, **1)** the string should have a complete value (`!string.IsNullOrEmpty`), and **2)** string is numeric (my solution) – Scott Sep 28 '17 at 19:23
  • I have already done it that way but I would love it if I could handle all in one condition. – M. Fawad Surosh Sep 28 '17 at 19:27
  • @M.FawadSurosh In that case, the `IsNumeric` extension method from my answer might work for you. It simply tries to parse the string as a float, which will handle decimals, negatives, numbers like `1e3`, etc. – Scott Sep 28 '17 at 19:31
3

How about some easy LinQ?

if (str.Take(4).All(char.IsDigit) { ... }
AgentFire
  • 8,944
  • 8
  • 43
  • 90