4

我正在处理字符串,我想知道哪种方法最好检查字符串是否只包含指定的字符集:

@  ∆  SP  0  ¡  P  ¿  p 
£  _  !  1  A  Q  a  q 
$  Φ  "  2  B  R  b  r 
¥  Γ  #  3  C  S  c  s 
è  Λ  ¤  4  D  T  d  t 
é  O  %  5  E  U  e  u 
ù  Π  &  6  F  V  f  v 
ì  Ψ  '  7  G  W  g  w 
ò  Σ  (  8  H  X  h  x 
Ç  Θ  )  9  I  Y  i  y 
LF  Ξ  *  :  J  Z  j  z 
Ø  1)  +  ;  K  Ä  k  ä 
ø  Æ  ,  <  L  Ö  l  ö 
CR  æ  q  =  M  Ñ  m  ñ 
Å  ß  .  >  N  Ü  n  ü 
å  É  /  ?  O  §  o  à 

我试图通过 eregi 和 regexp 来完成它,但没有成功。另一种方法是将每个字符转换为十进制并检查它是否小于< 137,或者通过 in_array() 检查每个元素 - 我发现它很弱。

有人有更好的解决方案吗?

提前致谢。

4

6 回答 6

10

我看到您已经接受了另一个答案,但我想解释一下为什么您使用正则表达式的尝试不起作用。希望它会帮助你。

首先,我注意到这个问题的标签中有。请注意 PHP 的ereg_函数已被弃用;你应该只使用这些preg_功能。

现在,如果您想对此类事情使用正则表达式,您通常会使用否定字符类来定义要允许的字符列表,然后查找其他任何内容。

字符类是用方括号括起来的字符列表。您可以通过在开头添加克拉符号来否定字符类。因此,如果您想要一个仅包含“A”、“B”或“C”的字符串,并且您希望收到有关包含其他任何内容的字符串的警告,您可以使用以下内容:

$result = preg_match("/[^ABC]/",$mystring);

您的示例基本相同(但显然要测试更多字符),除了两点:首先,您的列表中有字符是正则表达式中的保留字符,其次,您使用的是非 Ascii 字符。

可以通过使用前导反斜杠将它们转义来处理正则表达式保留字符。您只需要知道保留了哪些字符。查看您的列表,我看到?/和。.+

第二点解释了为什么你不能让它工作ereg,因为这些ereg函数不支持 unicode。改用这些preg功能,你会有更多的运气。

您仍然需要向正则表达式引擎指定您要查找的 unicode 字符。这是通过将u修饰符添加到正则表达式字符串的末尾来完成的。

因此,您的查询的缩短版本可能如下所示:

$result = preg_match("/[^èΛ¤4DTdt]/u",$mystring);

看起来您在字符列表中添加了新行,因此您可能还想在m旁边添加多行修饰符u

对于无法写入的字符(或者实际上对于任何字符,如果更容易的话),您可以为其 unicode 字符代码添加转义序列。使用\uFFFFwhereFFFF是您要匹配的字符的十六进制 unicode 参考 - 例如\u00E0匹配à

我希望这能让您更好地了解正则表达式。我应该补充一点,我并不是说正则表达式一定是这个问题的最佳解决方案,也不一定是唯一的解决方案。我试图通过使用否定字符类使其性能达到最佳(这意味着它一旦找到不匹配的字符就会失败,并且应该防止那种可能导致正则表达式有时非常慢的过度回溯),所以它应该是合理的性能,但我还没有针对其他解决方案对其进行测试。

我希望这会有所帮助。

于 2011-07-08T09:35:31.543 回答
3

就您对单字节字符集而言,您可以使用字符串函数:

$charset = 'abc';
$test = 'abcd';
$ofCharset = strlen($test) === strspn($test, $charset); # FALSE

否则,您必须将字符串拆分为每个一个字符的数组条目,然后与一个字符表进行比较,该字符表可能是一个键控数组,也包含字符集的字符作为键。

于 2011-07-06T19:16:43.070 回答
1

为了保持操作 O(n),您可以计算每个测试字符的 ascii 值并将它们放入哈希表中,如下所示:

$testChars[$ascii] = true;

然后只需遍历主题字符串的字符并测试哈希表值条目是否已设置并等于 true。如果任何字符为假,则它包含不在您的测试集中的字符。

这会比使用 in_array 更好,因为测试 $testChars[$ascii] == true 是一个常数 O(1) 查找。

于 2011-07-06T18:53:56.127 回答
0

我知道这是一个老问题,但没有人提到strpbrk。我从来没有尝试过使用奇怪的字符,但除了这可能是一个问题之外,为什么这不起作用?

于 2013-11-11T02:56:00.680 回答
0

这是一个很好的资源,可以帮助您找到答案。

高级正则表达式技巧和技巧

于 2011-07-06T18:42:30.227 回答
0

if your trying to find out only if there are other characters you could just str_replace the character set to "" and then get the strlen ... If it is 0 then only those characters are there... if greater then 0 then other characters exist.

ex.

$mystr = "macguffin";
$mycharset = array('m', 'a', 'c', 'g', 'u', 'f', 'i', 'n');

$tmpstr = str_replace($mycharset, "", $mystr);

if (!strlen($tmpstr)) {
    echo "only charset chars";
} else {
    echo "other chars";
}

would return

only charset chars

but

$mystr = "macguffin";
$mycharset = array('m', 'a', 'c');

$tmpstr = str_replace($mycharset, "", $mystr);

if (!strlen($tmpstr)) {
    echo "only charset chars";
} else {
    echo "other chars";
}

would return

other chars

HTH

于 2011-07-06T20:13:34.513 回答