Випадковий рядок PHP - це рядок з великими іменниками, що використовують знайомі словники?

Мені потрібно шукати рядок слів за словником слів (txt-файл) і заголовувати будь-яке слово, яке не знайдено.

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 )

Словник відкривається та вставляється в масив за допомогою 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;
}

Я підтвердив, що файл відкривається.

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

Редагувати:

Скориставшись відповіддю нижче Джей, я запропонував дієве рішення. Моя перша проблема полягала в тому, що словник моїх слів містив як великими, так і небагатословами словами, тому я знайшов словник власних імен, щоб перевірити використання зворотного виклику регулярного виклику. Це не ідеально, але він отримує його більшу частину часу.

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
exceptions продовжує перевизначатися, тому він матиме лише останній рядок. Не впевнений, що це проблема (або лише проблема), однак
додано Автор Explosion Pills, джерело
Звичайно, це неможливо отримати 100% точності з таким підходом; занадто багато власних іменників є також звичайними іменниками (Нік, Польська, ...).
додано Автор Keith Thompson, джерело
Я думаю, у вас є кілька проблем, і ви повинні задавати своє питання про одну проблему тільки для отримання кращих відповідей. Виділіть свої проблеми, а потім виправити один за одним.
додано Автор hakre, джерело
Замість того, щоб вибухати ваш рядок і цикл для кожного слова, чому б не просто зробити preg_replace або str_replace на рядок у цілому?
додано Автор Bart, джерело
/ usr/dict/words включає деякі знакові займенники, IIRC ...
додано Автор Frank Farmer, джерело
Питання зрозуміло.
додано Автор Chris_O, джерело

1 Відповіді

Найпростіший спосіб зробити це за допомогою регулярного виразу: зробити наступне

  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

Прикладом робочої демонстрації є це

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

1
додано
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php