PHP Sentence case是一个使用已知单词字典的大写专有名词的字符串?

时间:2011-10-27 17:58:42

标签: php regex string fopen fgets

我需要针对单词词典(txt文件)搜索一串单词,并将任何未找到的单词大写。

我正在尝试将字符串拆分为单词数组,并针对unix / usr / dict / words字典进行检查。如果找到匹配单词,则匹配lcfirst($word)如果不匹配则ucfirst( $word )

使用fgetcsv打开字典并将其放入数组中(我也尝试使用fgets并在行尾爆炸)。

function wnd_title_case( $string ) {
$file = fopen( "/users/chris/sites/wp-dev/trunk/core/words.txt", "rb" );
while ( !feof( $file ) ) {
    $line_of_text = fgetcsv( $file );
     $exceptions = array( $line_of_text );
}


fclose( $file );
    $delimiters = array(" ", "-", "O'");
         foreach ( $delimiters as $delimiter ) {
            $words = explode( $delimiter, $string );
            $newwords = array();
                 foreach ($words as $word) {
                if ( in_array( strtoupper( $word ), $exceptions ) ) {
           // check exceptions list for any words that should be lower case
            $word = lcfirst( $word );
            } elseif ( !in_array( $word, $exceptions ) ) {
       // everything else capitalized
            $word = ucfirst( $word );
         }
       array_push( $newwords, $word );
       }
    $string = join( $delimiter, $newwords );
   }
        $string = ucfirst( $string );
   return $string;
}

我已经确认该文件已被打开。

所需的输出:具有专有名词大写的句子标题字符串。
当前输出:每个单词大写的标题字符串

编辑:

使用Jay的答案,我想出了一个可行的解决方案。我的第一个问题是我的单词字典包含大写和非大写单词,因此我找到了一个正确的名称字典来检查使用正则表达式回调。它并不完美,但大部分时间都是正确的。

function title_case( $string ) {
    $fp = @fopen( THEME_DIR. "/_/inc/propernames", "r" );  
        $exceptions = array();
        if ( $fp ) {

            while( !feof($fp) ) {
                    $buffer = fgets( $fp );
                array_push( $exceptions, trim($buffer) );
            }

        }

    fclose( $fp );

    $content = strtolower( $string );
    $pattern = '~\b' . implode ( '|', $exceptions ) . '\b~i';
    $content =  preg_replace_callback (  $pattern, 'regex_callback', $content  );
    $new_content =  $content;

    return ucfirst( $new_content );
}

    function regex_callback ( $data ) {
        if ( strlen( $data[0] )  > 3 )
        return ucfirst( strtolower( $data[0] ));
        else return ( $data[0] );

    }

1 个答案:

答案 0 :(得分:1)

使用正则表达式执行此操作的最简单方法是执行以下操作

  1. 将您的文字转换为全部大写的第一个字母$content = ucwords($original_content);
  2. 使用字典中的单词数组,通过使用竖线字符|对所有单词进行内爆,然后使用边框标记和分隔符,然后使用不区分大小写的标记来创建正则表达式,这样您最终会使用~\bword1|word2|word3\b~i(显然是您的大型列表)
  3. 使用strtolower创建一个降低匹配值的函数,以便与preg_replace_callback一起使用
  4. 工作演示的一个例子就是这个

    function regex_callback($data) {
        return strtolower($data[0]);
    }
    
    $original_content = 'hello my name is jay gilford';
    $words = array('hello', 'my', 'name', 'is');
    
    $content = ucwords($original_content);
    $pattern = '~\b' . implode('|', $words) . '\b~i';
    
    $content = preg_replace_callback($pattern, 'regex_callback', $content);
    
    echo $content;
    

    您还可以选择使用strtolower开始内容以保持一致性。上面的代码输出hello my name is Jay Gilford