uncovery
uncovery

Reputation: 878

Counting letters in a string by type in PHP

I want to find out how many lettes/numbers, punctuation marks and '$' sings are in a string. I am trying a set of 3 regexes with preg_match_all:

Let's say I have a string such as $string = "abcde!@#$%$$";

for the count of $: I tried

$check = preg_match_all("/(\$)/", $string, $matches);

which should give me 3 matches. But a var_dump of $matches give me this here:

array ( 0 => array ( 0 > '', ), 1 => array ( 0 => '', ),)

similarly, I tried to match all letters and punctuation with the patterns '/(\w)/' and '/(\W)/' respectively, but there I do not get any matches. Why?

Btw I know that \W also matches '$'.

Upvotes: 1

Views: 1063

Answers (3)

Jonny 5
Jonny 5

Reputation: 12389

$str = "abcde!@#$%$$1234567";

$count_negated = array(
  'ALPHA' =>  '[^[:alpha:]]+',
  'ALNUM' =>  '[^[:alnum:]]+',
  'DIGITS' => '\D+',
  'DOLLAR' => '[^$]+',
  'PUNCT' =>  '[^[:punct:]]+'
);

foreach($count_negated AS $k => $v)
{
  echo "There are ".
        strlen(preg_replace('~'.$v.'~', "", $str))." ".$k.
        " in my string<br>";
}

output:

There are 5 ALPHA in my string
There are 12 ALNUM in my string
There are 7 DIGITS in my string
There are 3 DOLLAR in my string
There are 7 PUNCT in my string

Upvotes: 1

Sam
Sam

Reputation: 20486

You can combine this into 1 RegEx: /([\w])|([!,\.])|(\$)/.

This will match 1: words (alphanumeric), 2: punctuation (!, ,, ., or whatever you add to the class), and 3: dollar signs. Then you can loop through preg_match_all() to get the counts:

<?php
$alphanumeric = $punctuation = $dollar = 0;

if(preg_match_all('/([\w])|([!,\.])|(\$)/', 'abcde!@#$%$$', $matches)) {
    for($i = 1; $i <= 3; $i++) {
        $count = 0;
        foreach($matches[$i] as $match) {
            if($match)
              $count++;
        }

        switch($i) {
            case 1: $alphanumeric = $count; break;
            case 2: $punctuation = $count; break;
            case 3: $dollar = $count; break;
        }
    }
}

var_dump($alphanumeric); // int(5)
var_dump($punctuation); // int(1)
var_dump($dollar); // int(3)

Obviously, the 3 matching groups ([\w], [!,\.], \$) can be modified or added to depending on your needs.

Upvotes: 1

elclanrs
elclanrs

Reputation: 94121

Use single quotes, otherwise PHP thinks you want to interpolate given the dollar sign:

$check = preg_match_all('/(\$)/', $string, $matches);
                        ^      ^

That should do. Also you don't need the capturing group: '/\$/'

I don't see a problem with the other regex. '/\W/' outputs 7, and '/\w/' outputs 5.

Upvotes: 3

Related Questions