Kyle Burns
Kyle Burns

Reputation: 167

How to check if a string contains certain characters using an array in php

I need to check if a string contains illegal character and I was wondering if there is a way to do it through an array because I have an array character that are allowed. This is in PHP

The array just in case you want to see it:

$MsgAry1 = array("A","B","C","D","E","F","G","H","I","J",
           "K","L","M","N","O","P","Q","R","S","T",
           "U","V","W","X","Y","Z","a","b","c","d",
           "e","f","g","h","i","j","k","l","m","n",
           "o","p","q","r","s","t","u","v","w","x",
           "y","z","1","2","3","4","5","6","7","8",
           "9","0",".",",","'","?","!"," ","_","-");

Thanks for any help.

Upvotes: 0

Views: 6978

Answers (5)

mickmackusa
mickmackusa

Reputation: 47874

You don't need to loop ...but if you did use a loop, then you'd better use an early return/break so that you aren't doing unnecessary iterations after you've found a disqualifying character.

In a project of my own, I'd prefer to store the regex expression instead of an array of characters -- it's just more concise and direct.

If you must an array of characters, you can avoid the explode and loop by trimming all of the safe characters and check if any characters remain after trimming.

Code: (Demo)

$MsgAry1 = ["A","B","C","D","E","F","G","H","I","J",
           "K","L","M","N","O","P","Q","R","S","T",
           "U","V","W","X","Y","Z","a","b","c","d",
           "e","f","g","h","i","j","k","l","m","n",
           "o","p","q","r","s","t","u","v","w","x",
           "y","z","1","2","3","4","5","6","7","8",
           "9","0",".",",","'","?","!"," ","_","-"];

$strings = [
    'test',
    '1234',
    'w0ws3r!',
    '##tag##',
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,'?! _-"
];

foreach ($strings as $string) {
    echo "$string match: " . var_export(!preg_match("~[^\w.,'?! -]~", $string), true) . "\n";
    echo "$string ltrim:  " . var_export(!strlen(ltrim($string, implode($MsgAry1))), true) . "\n";
    echo "$string after trim: \"" . ltrim($string, "A..Za..z0..9.,'?! _-") .  "\"\n---\n";
}

Output:

test match: true
test ltrim:  true
test after trim: ""
---
1234 match: true
1234 ltrim:  true
1234 after trim: ""
---
w0ws3r! match: true
w0ws3r! ltrim:  true
w0ws3r! after trim: ""
---
##tag## match: false
##tag## ltrim:  false
##tag## after trim: "##tag##"
---
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,'?! _- match: true
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,'?! _- ltrim:  true
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,'?! _- after trim: ""
---

!strlen(ltrim($string, "A..Za..z0..9.,'?! _-")) demonstrates that you can use multiple character ranges in the "character mask" parameter so long as you use .. to indicate each range. I believe this is the most concise, non-regex technique. Again, if the trimmed string has length, then at least one bad character was found.

No matter which technique you prefer, I strongly discourage iterated calls of in_array() -- the performance cost will balloon as the length of the input string increases.

Upvotes: 0

Dan
Dan

Reputation: 580

Here's a non-iterative method, which should perform faster than the existing answers that loop.

function containsIllegalChars($testString) {
    static $MsgAry1 = array("A","B","C","D","E","F","G","H","I","J",
           "K","L","M","N","O","P","Q","R","S","T",
           "U","V","W","X","Y","Z","a","b","c","d",
           "e","f","g","h","i","j","k","l","m","n",
           "o","p","q","r","s","t","u","v","w","x",
           "y","z","1","2","3","4","5","6","7","8",
           "9","0",".",",","'","?","!"," ","_","-");
    $foundCount = 0;
    str_replace($MsgAry1, '', $testString, $foundCount);
    return $foundCount > 0;
}

You can make it even more efficient with your specific set of letters by removing all the uppercase letters, and using str_ireplace.

function containsIllegalChars($testString) {
    static $MsgAry1 = array("a","b","c","d",
           "e","f","g","h","i","j","k","l","m","n",
           "o","p","q","r","s","t","u","v","w","x",
           "y","z","1","2","3","4","5","6","7","8",
           "9","0",".",",","'","?","!"," ","_","-");
    $foundCount = 0;
    str_ireplace($MsgAry1, '', $testString, $foundCount);
    return $foundCount > 0;
}

Upvotes: 3

Acharya Anurag
Acharya Anurag

Reputation: 661

You can use the str_split and in_array functions to do this, as thus:

$MsgAry1 = array("A","B","C"); //Add your actual array here
$testCase = "Hello, World!";
$testCase_arr = str_split($testCase);

foreach($testCase as $test)
{
    if(!in_array($test, $MsgAry1))
    {
        echo "Error! Invalid Character!";
        break(); //Or exit();, as needed
    }
}

Upvotes: 5

Vaishu
Vaishu

Reputation: 2363

$resultarray = preg_replace("/[^A-Za-z0-9]/", "", $MsgAry1);
print_r ($resultarray);

Upvotes: 2

michelem
michelem

Reputation: 14590

You could use something like this, str_split splits the string into characters then you can check each one with in_array:

$MsgAry1 = array("A","B","C","D","E","F","G","H","I","J",
           "K","L","M","N","O","P","Q","R","S","T",
           "U","V","W","X","Y","Z","a","b","c","d",
           "e","f","g","h","i","j","k","l","m","n",
           "o","p","q","r","s","t","u","v","w","x",
           "y","z","1","2","3","4","5","6","7","8",
           "9","0",".",",","'","?","!"," ","_","-");

$string = "Hello";

foreach (str_split($string) as $char) {
        if (in_array($char, $MsgAry1)) {
            echo "Char: ".$char." -> OK";
        } else {
            echo "Char: ".$char." -> KO";
        }   
}

Upvotes: 2

Related Questions