字母表中的每个字母至少有一次字符串吗?

时间:2017-05-15 16:11:27

标签: php regex

想知道是否有更有效的方法来检测字符串是否包含使用正则表达式一次或多次字母表中的每个字母?

我感谢任何建议

$str = str_split(strtolower('We promptly judged antique ivory buckles for the next prize'));

$az = str_split('abcdefghijklmnopqrstuvwxyz');

$count = 0;
foreach($az as $alph) {
    foreach($str as $z) {
        if($alph == $z) {
           $count++;
            break;
        }
    }
}

5 个答案:

答案 0 :(得分:5)

只需使用array_diff

count(array_diff($az, $str)) > 0;

答案 1 :(得分:3)

使用正则表达式,你可以做到这一点,但它不是最佳的,也不是快速的,@ hjpotter方式,如果从更快的方式:

var_dump(strlen(preg_replace('~[^a-z]|(.)(?=.*\1)~i', '', $str)) == 26);

删除所有非字母字符,所有重复字母(不区分大小写),并将字符串长度与26进行比较。

  • [^a-z]匹配任何非字母字符
  • (.)捕获第1组的信件
  • (?=.*\1)检查同一个字母是否在其他地方(右侧)
  • i修饰符使模式不区分大小写

答案 2 :(得分:2)

我没有任何正则表达式的答案。但是如果没有正则表达式,您可以尝试使用PHP的count_chars函数。

例如:

$test_string = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
echo count(count_chars($test_string, 1));

给你26 - 这是$ test_string中频率大于零的唯一字符数。

答案 3 :(得分:0)

您当前的程序将为所有包含26个以上字母的字符串打印pangram,这意味着,即使aaa...也是一个庞格拉姆。

在内循环中,如果找不到a-z中的任何字符,则可以中断:

function is_pangram($str) {
  if (strlen($str) < 26) return false; 
  $az = str_split('abcdefghijklmnopqrstuvwxyz');
  for ($az as $char) {
    if (stripos($str, $char) === false)
      return false;
  return true;
  }
}

在这种情况下,正则表达式不是最优的。另一种方法是使用array_mapstr_count

答案 4 :(得分:0)

制作一个长度为26的布尔数组。然后你只需循环一次你的字符串。在伪代码中(因为我不懂PHP):

Boolean b[26]; // Initialized to false
count = 0;
Loop for each char c in string
   if (not b[c]) then
      ++count;
      b[c] = true
   end
   if (count == 26)
     break;  // All present;
   end
end
// If count < 26 then not all present

你需要弄清楚如何将角色索引放入数组中,但这不应该太难。