Sean Conaty
Sean Conaty

Reputation: 23

Regex issue for string matching and NOT matching

Brand new to Javascript and read quite a bit but cant seem to get this right. I have dType linked to an onclick event within an HTML page. I cannot seem to get the syntax correct for the first else if statement where I would like the alert to occur if the user input is not a number and the input does not match 'true' or 'false'. The second else if seems to be matching any string of equal length while I though this was making the array items case insensitive. For the 4th is else, I was hoping to alert upon the user entering and value between -infinity and infinity. the end goal is to provide some information about possible datatype despite the fact that, technically, anything entered into the prompt is a string. As much as I know there is alot of documentation on all of this I have been reading for hours and hoped asking directly would help me learn about what is going on here. Thanks to anyone who took the time to read this despite its poor construction.

function dType() {
    var inputP= prompt("Type something Nice and Ill tell you something useful:");

    if (inputP === "") {
 	    alert('At least give me something...');
    } else if (isNaN(inputP)) && inputP.match(^(?!'true' || 'false').)*$){
 	    alert('This is a String');
    } else if inputP.match(/['true','false']/i){
	    alert('This might be a boolean');
    } else if inputP.match(/\d+/g){
	    alert('This has some numbers in it')
    } else if inputP = (inputP > MATH.min('') && inputP < MATH.max('')){
        alert('this is a number')
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

Views: 1012

Answers (2)

xec
xec

Reputation: 18024

There seems to be a couple of issues with the first else/if

} else if (isNaN(inputP)) && inputP.match(^(?!'true' || 'false').)*$){

let's break it down. First you seem to have an extra )after the isNaN call

isNan(inputP) // <-- ends the isNaN call
if (isNan(inputP)) // <-- ends the if condition
if (isNan(inputP) && ...) // what you probably wanted

That said, isNaN checks explicitly if a value is literally NaN, which will never be the case from a prompt(), so I would just remove that.

Secondly, you need to wrap your regex in / like so: /^(?!'true' || 'false').)*$/, as pointed out by T.J. it can also be made a bit simpler.

...for the first else if statement where I would like the alert to occur if the user input is not a number and the input does not match 'true' or 'false'

You could rearrange the order to simply match true/false, then check for digits etc, to make each if statement simpler;

if (!inputP) { // an empty string is "falsy"
    // at least give me something
} else if (/^(true|false)$/.test(inputP)) {
    // inputP is "true" or "false"
} else if (/^\d+$/.test(inputP)) {
    // inputP contains only numbers
} else if (/\d+/.test(inputP)) {
    // inputP contains some numbers
} else {
    // inputP is a string
}

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074248

Your first else if contains syntax errors, mostly because you haven't put the regular expression in regex quotes (/.../).

The expression I think you're trying to use is also more complicated than it needs to be for what you've said you want, it can just be:

} else if (isNaN(inputP)) && !inputP.match(/^(?:true|false)$/)) {

...which means "match the start of input, followed by true or false, followed by the end of input". (You were right you needed a group to ensure the alternation (|) only applies to the true/false and not the ^ and $; you used a capture group, which is okay; I used a non-capturing group instead above -- (?:...) -- as we don't use the captured text.) Then we negate the result (the !) because you don't want to match those.

But typically, if you just want to know whether something matches, rather than String#match you'd use RegExp#test:

} else if (isNaN(inputP)) && !/^(?:true|false)$/.test(inputP)) {

There are several other issues, however:

  • You need to consistently have parens around the conditions in an if

  • The second else if matches any character listed between the [ and ], not a pair of choices

  • The conditions can be reordered to avoid duplicate checks

  • To check for infinity, you can use !isFinite

  • You need to either use or not use the i flag to ignore case consistently if you're going to check for something twice

Since we can't use alert and prompt in Stack Snippets, here's an example using an input field instead with a few of the above fixed:

$("input[type=button]").on("click", function() {
  dType($("input[type=text]").val());
});

function dType(inputP) {
  if (inputP === "") {
    show('At least give me something...');
  } else if (/^(?:true|false)$/i.test(inputP)) {
    show('This might be a boolean');
  } else if (isNaN(inputP)) {
    show('This is a String');
  } else if (!isFinite(inputP)) {
    show('this is infinity')
  } else if (isFinite(inputP)) {
    show('this is a number')
  } else if (/\d+/.test(inputP)) {
    show('This has some numbers in it')
  } else {
    show("dunno");
  }
}

function show(msg) {
  $("<p>").text(msg).appendTo(document.body);
}
<input type="text" id="prompt">
<input type="button" value="Go">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 2

Related Questions