验证输入字符串未超过单词限制。

15

我想计算一个特定字符串中的单词数量,以便验证它并防止用户编写超过100个单词。 我编写了这个函数,但我认为它不够有效。 我使用了空格作为分隔符的explode函数,但如果用户输入两个空格而不是一个空格怎么办? 你能给我更好的方法吗?

function isValidLength($text , $length){
  
   $text  = explode(" " , $text );
   if(count($text) > $length)
          return false;
   else
          return true;
}

https://dev59.com/ymEi5IYBdhLWcg3wG41o - trante
你可能会发现count(s($str)->words())很有用,这在这个独立库中可以找到。 - caw
10个回答

25

只有一个人提到了 str_word_count。这个函数不适合吗? - Francesco Laurita
16
str_word_count 很烂!如果它包含在更长的单词中,比如“theme”、“theory”等,则会多次计算“the”的出现次数。str_word_count 很差劲,我在 stackoverflow 上经常看到这种情况。 - giorgio79
7
你能提供一个备选方案,而不是像疯子一样发牢骚吗? - Henrik Petterson
此函数也将连字符视为单词。在使用 preg_replace 替换所有非字母字符(例如:str_word_count(preg_replace('/[^a-z]+/i', ' ', $string)))后,我发现使用此函数更好。 - TURTLE
str_word_count会将"Yet"和"yet"视为两个不同的单词。我想这是公平的。可以在测试前将字符串转为小写来解决这个问题。 - prog_24
str_word_count() 函数出于某种原因始终返回 1。 - mrid

21

试试这个:

function get_num_of_words($string) {
    $string = preg_replace('/\s+/', ' ', trim($string));
    $words = explode(" ", $string);
    return count($words);
}

$str = "Lorem ipsum dolor sit amet";
echo get_num_of_words($str);

这将输出:5


6
迄今为止,这实际上是最好的答案,既简洁又没有严重问题。但我会将函数主体简化为 return count(explode(' ', preg_replace('/\s+/', ' ', trim($string)))); - orrd
为什么不直接使用 preg_split() 而要准备字符串再用 explode()?这个回答还不够优雅。 - mickmackusa

10
你可以使用内置的PHP函数str_word_count。像这样使用它:
$str = "This is my simple string.";
echo str_word_count($str);

这将输出5。

如果您打算在任何单词中使用特殊字符,可以将任何额外的字符提供为第三个参数。

$str = "This weather is like el ninã.";
echo str_word_count($str, 0, 'àáã');

这将输出6。


4
PHP太棒了,其标准库中包含了你所需要的一切。只是这个小小的makeBlog()函数还没有。 - NikiC
@Michael Irigoyen:他可能是以修辞方式问“为什么PHP有这么多函数?” - BoltClock
2
此函数无法处理非ASCII字符(例如带重音的字母)。str_word_count("déjà")输出2。 - Arnaud Le Blanc
1
@auser576875:a)它取决于区域设置,b)您可以进一步指定“单词”字符。 - NikiC
@nikic LC_ALL=fr_FR.UTF-8,仍然输出2 :) $charlist参数在处理多字节字符时效果不佳。 - Arnaud Le Blanc
哦等等,让我调用post_reply_to_latest_stackoverflow_comment(':P'); - Blender

4
此函数使用简单的正则表达式在任何非字母字符上分割输入的$text:
function isValidLength($text, $length) {
    $words = preg_split('#\PL+#u', $text, -1, PREG_SPLIT_NO_EMPTY);
    return count($words) <= $length;
}

这可以确保它正确处理由多个空格或任何其他非字母字符分隔的单词。它还可以正确处理 Unicode(例如,带重音符号的字母)。

当单词数少于 $length 时,该函数返回 true。


4

str_count_words有其缺陷。它会将下划线视为分隔单词的符号,例如this_is被视为两个单词:

您可以使用下一个函数来计算由空格分隔的单词,即使它们之间有多个空格。

function count_words($str){

    while (substr_count($str, "  ")>0){
        $str = str_replace("  ", " ", $str);
    }
    return substr_count($str, " ")+1;
}


$str = "This   is  a sample_test";

echo $str;
echo count_words($str);
//This will return 4 words;

2
使用 preg_split() 代替 explode()。Split 支持正则表达式。

1
如果您需要更好地定义“单词”在应用程序的上下文中,则调用preg_match_all()返回其匹配计数。如果您需要多字节支持,则添加Unicode模式修饰符。\pL\pM是字母和字母标记,以包容为主。将其视为起点,并了解可以根据需要收紧或放宽正则表达式规则来定义“单词”的定义。 此解决方案支持多字节。 代码:(演示)(Regex101演示
function isValidLength($text, $length) {
    return $length <= preg_match_all("~[\pL\pM'-]+~u", $text);
}

如果这是必填字段,且你只需要计算以空格分隔的“非空白子字符串”,那么你可以直接编写以下内容:

if (preg_match("~^\s*\S+(\s+\S+){0,99}\s*$~", $text)) { ... }

或者

if (preg_match("~^\S+(\s+\S+){0,99}$~", trim($text))) { ... }

0

在 n 个对象之间有 n-1 个空格,因此在 100 个单词之间将有 99 个空格,所以您可以选择一个平均长度为 10 个字符的单词,然后乘以 100(对于 100 个单词),再加上 99(空格),然后您可以根据字符数(1099)来限制。

function isValidLength($text){

如果(strlen($text) > 1099)

     return false;

否则 返回真;

}


0

使用substr_count函数来计算任何子字符串出现的次数。如果要查找单词数,请将$needle设置为' '。 int substr_count ( string $haystack , string $needle)

$text = 'This is a test';
echo substr_count($text, 'is'); // 2


echo substr_count($text, ' ');// return number of occurance of words

1
这里有几个问题。它计算的是空格,而不是单词。因此,如果只有一个单词,它将返回0。并且它会将多个空格计算为一个单词(例如,如果您在每个句号后面放两个空格,通常会这样做)。 - orrd

0

我写了一个比str_word_count更好的函数,因为PHP函数会将破折号和其他字符计算为单词。

此外,我的函数解决了双空格的问题,而许多其他人编写的函数没有考虑到这一点。

此函数还处理HTML标签。如果您有两个标签嵌套在一起,并且简单地使用strip_tags函数,那么当它是两个单词时,这将被计算为一个单词。例如:<h1>Title</h1>Text<h1>Title</h1><p>Text</p>

此外,我先删除JavaScript,否则<script>标签内的代码将被计算为单词。

最后,我的函数处理字符串开头和结尾的空格、多个空格以及换行符、回车符和制表符。

###############
# Count Words #
###############
function count_words($str)
{
 $str = preg_replace("/[^A-Za-z0-9 ]/","",strip_tags(str_replace('<',' <',str_replace('>','> ',str_replace(array("\n","\r","\t"),' ',preg_replace('~<\s*\bscript\b[^>]*>(.*?)<\s*\/\s*script\s*>~is','',$str))))));
 while(substr_count($str,'  ')>0)
 {
  $str = str_replace('  ',' ',$str);
 }
 return substr_count(trim($str,' '),' ')+1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接