drbz99867 2011-10-27 17:58
浏览 78
已采纳

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

I need to search a string of words against a dictionary of words(txt file) and capitalize any word that is not found.

I'm trying to split the string into an array of words and check them against the unix /usr/dict/words dictionary. If a match is found for the word it gets lcfirst($word) if no match then ucfirst( $word )

The dictionary is opened and put into an array using fgetcsv (I also tried using fgets and exploding on end of line).

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

I have verified that the file gets opened.

The desired output: Sentence case title string with proper nouns capitalized.
The current output: Title string with every word capitalized

Edit:

Using Jay's answer below I came up with a workable solution. My first problem was that my words dictionary contained both capitalized and non capitalized words so I found a proper names dictionary to to check against using a regex callback. It's not perfect but gets it right most of the time.

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条回答 默认 最新

  • doutu6658 2011-11-26 17:21
    关注

    The simplest way to do this with regex is to do the following

    1. convert your text to all uppercase first letters $content = ucwords($original_content);
    2. Using your array of words in the dictionary, create a regex by imploding all your words with a pipe character |, and surrounding it with boundary markers and delimiters followed by the case insensitive flag, so you would end up with ~\bword1|word2|word3\b~i (obviously with your large list)
    3. create a function to lower the matched value using strtolower to be used with preg_replace_callback

    An example of a working demo is this

    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;
    

    You could also optionally use strtolower to begin with on the content for consistency. The above code outputs hello my name is Jay Gilford

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?