如何检查字符串是否只包含指定的字符集


How to check if string contains only specified character set?

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

@  ∆  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()检查每个元素-我发现这很弱。

谁有更好的解决方案?

我看到您已经接受了另一个答案,但是我想解释一下为什么您使用regex的尝试不起作用。希望它能帮到你。

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

现在,如果你想使用正则表达式来处理这类事情,你通常会使用一个反字符类来定义一个你想允许的字符列表,然后寻找其他的。

字符类是用方括号括起来的字符列表。您可以通过在字符类的开头添加一个carat符号来否定它。如果你想要一个只包含' a ', 'B'或'C'的字符串,并且你想要警告包含其他内容的字符串,你可以使用这样的东西:

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

你的例子基本上是相同的(但有更多的字符测试,显然),除了两点:首先,你有字符在你的列表是保留字符在Regex,其次,你使用非ascii字符。

可以通过使用前导反斜杠转义来处理Regex保留字符。你只需要知道哪些字符是保留的。看你的清单,我看到了?, /, .+

第二点解释了为什么不能使用ereg,因为ereg函数不支持unicode。切换到使用preg函数,你会有更多的运气。

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

因此,您的查询的缩短版本可能看起来像这样:

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

看起来你在字符列表中包含了新的行,所以你可能还想在u旁边添加多行修饰符m

对于不能写的字符(或者任何字符,如果更容易的话),您可以为其unicode字符代码添加转义序列。使用'uFFFF,其中FFFF是您想要匹配的字符的十六进制unicode引用——例如'u00E0匹配à

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

就您所关心的单字节字符集而言,您可以使用字符串函数:

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

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

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

$testChars[$ascii] = true;

然后循环遍历主题字符串的字符,并测试哈希表值条目是否设置并等于true。如果任何一个字符的值为false,则该字符包含不在测试集中的字符。

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

这里有一个很好的资源可以帮助你找到答案。

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

如果你试图找出只有如果有其他字符,你可以只是str_replace字符集为",然后得到strlen…如果它是0,那么只有这些字符在那里…如果大于0,则表示存在其他字符。

$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";
}

回来
only charset chars

,

$mystr = "macguffin";
$mycharset = array('m', 'a', 'c');
$tmpstr = str_replace($mycharset, "", $mystr);
if (!strlen($tmpstr)) {
    echo "only charset chars";
} else {
    echo "other chars";
}

将返回

other chars

HTH

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