1

I have a string like this:

$str = "this is a test";

I want to validate $str and return true if string is containing is and it isn't containing test. How can I do that?


Examples:

"this is a test"   // false
"this is a tes"    // true    "is" exists and "test" doesn't exist
"this iss a tes"   // false
"this iss a test"  // false

Here is my pattern \bis\b(?!test). But it seems to just checks existing, I mean it also returns true when test exists. I mean the result of following code us true which shouldn't be (because test exists).

if (preg_match ("/\bis\b(?!test)/","this is a test")) {
    return true;
} else {
    return false;
}

Note: I'm really insist on doing that by regex.

1
  • 1
    Downvoter please leave a comment and explain why?
    – Shafizadeh
    Commented May 31, 2016 at 13:07

6 Answers 6

3

use strpos

$str = "this is a test";
if (strpos($str, 'is') !== false && strpos($str, 'test') === false ) {
   return true;
} else {
  return false;
}
1
  • 2
    Also your solution doesn't support word boundary now ..!
    – Shafizadeh
    Commented May 31, 2016 at 13:05
2

Try using lookahed, both positive and negative:

^(?=.*\bis\b)(?!.*\btest\b).*

Explaining:

^              # stands for start of the string, both lookahed below will use it as anchor

(?=            # positive lookahed
    .*         # can have any amount of characters till
    \bis\b     # literal text "is" with boundaries
)              # if not succeed will fail the regex

(?!            # negative lookahead
    .*         # can have any amount of characters till
    \btest\b   # literal text "test" with boundaries
)              # if succeed will fail the regex

.*             # if the regex didn't fail till here, match all characters in this line
2
  • 2
    Why should the OP "try" this? A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO. Commented May 31, 2016 at 13:09
  • 1
    @Shafizadeh. My bad, I typed = twice, I've updated Commented May 31, 2016 at 13:20
1

You can do it like this:

^                       # anchor it to the beginning of the line
    (?:(?!\btest\b).)*  # makes sure no test can be matched
    \bis\b              # match is as a word
    (?:(?!\btest\b).)*  # same construct as above
$                       # anchor it to the end of the line

See a demo on regex101.com.

For a PHP code, see the following snippet:

<?php
$string = "this is a test
this is a tes
this iss a tes
this iss a test
this test is";

$regex = '~
            ^                       # anchor it to the beginning of the line
                (?:(?!\btest\b).)*  # makes sure no test can be matched
                \bis\b              # match is as a word
                (?:(?!\btest\b).)*  # same construct as above
            $                       # anchor it to the end of the line
          ~mx';

preg_match_all($regex, $string, $matches);
print_r($matches);
?>

Hint: Note that I have changed the answer after it has been accepted to correct flaws in the original answer).

0
1

Something like ^(?!.*\btest\b).*\bis\b.*$ so would be:

if (preg_match ("(^(?!.*\btest\b).*\bis\b.*$)","this is a test")) {
    return true;
} else {
    return false;
}

Ok so explanation then, although its obvious, it first checks 'test' doesnt exist with any number of characters before it and then makes sure 'is' does exist.

3
  • 2
    Why should the OP try "something like this"? A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO. Commented May 31, 2016 at 13:11
  • 1
    This one is pretty close to what I'm looking for .. thx +1 .. Just please apply \b on your pattern.
    – Shafizadeh
    Commented May 31, 2016 at 13:12
  • 1
    Ah yes sorry I missed that bit @Shafizadeh. Now added. :) Commented May 31, 2016 at 13:16
1

Please try this ^.?\bis\b(?:(?!\btest\b).)$

2
  • Actually I'm trying to do that by one integrated pattern .. also please add ! in the beginning of your second condition: && !preg_match('/test/',$a)
    – Shafizadeh
    Commented May 31, 2016 at 13:14
  • You can wrap text with backticks to format it as code. Commented May 31, 2016 at 13:22
0

Try this it work proper by regular expression

 $str = "this is a test";

     if (preg_match ("/is/",$str) && !preg_match ("/test/",$str)) {
      return false;
    } else {
        return true;
    }
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.