Php 对非英语字符使用ucwords

Php 对非英语字符使用ucwords,php,regex,Php,Regex,目前,我正在使用ucwords相关函数在连字符、点和撇号后生成大写字母: function ucwordsMore ($str){ $str = ucwords($str); $str = str_replace('- ','-',ucwords(str_replace('-','- ',$str))); // hyphens $str = str_replace('. ','.',ucwords(str_replace('.','. ',$str))); // do

目前,我正在使用ucwords相关函数在连字符、点和撇号后生成大写字母:

function ucwordsMore ($str){
    $str = ucwords($str);
    $str = str_replace('- ','-',ucwords(str_replace('-','- ',$str)));  // hyphens
    $str = str_replace('. ','.',ucwords(str_replace('.','. ',$str)));  // dots
    $str = preg_replace("/\w[\w']*/e", "ucwords('\\0')", $str);        // apostrophes

    return $str;
}
它对英文字母很有效。但是,非英语字母不能正确识别。例如,本文:

德尔尼耶使用了法国的“休息协定”(accordéons resteéTulle)

全文如下:

德尔尼耶使用了法国的“休息协定”(accordéOns ResteéTulle)

但我需要的是:

法兰西和平协议的使用


有什么想法吗?

在正确进行此类转换之前,您可能需要将其用于
LC\u CTYPE
,但还有一个问题是字符串的编码方式
ucwords
仅用于单字节编码文本。

看看Kohana UTF8类-

正如@Jon所提到的,您需要
使用locale
来实现影响使用该类的函数调用的大小写之间的关系。通常是
LC\u CTYPE

数字行为、排序、货币等也有常量。语言环境需要安装在您的机器上,或者通过插件或模块等提供。请仔细阅读

我根本不知道php语言环境,所以这里有一个Perl示例,它使用了与您不同的正则表达式方法。我不能很好地理解你的解决方案,希望你能从我这里得到一些想法

use locale;
use POSIX qw(locale_h);

setlocale(LC_CTYPE, "en_US");

$str = "La dernière usine française d'accordéons reste à Tulle";

$str =~ s/ (?:^|(?<=\s)|(?<=\w-)|(?<=\w\.)|(?<=\w\')) (\w) / uc($1) /xeg;

print "$str\n";
正则表达式

表单为s///find and replace
搜索
(?:#组
^#字符串的开头
|(?使用此选项:

function mb_ucwords ($string)
{
    return mb_convert_case ($string, MB_CASE_TITLE, 'UTF-8'); 
}

英语字母到底是什么?它是拉丁字母表。根据你的例子,问题似乎在于重音字母。不过我认为手风琴的A是正确的,你不能指望
php
知道一个新词前面没有空格,撇号也不是一个好的分隔符,因为它不是一个空格总是表示end/start.php这个词对于正确处理Unicode非常有用;抱歉,但是在php中,一些在Perl中是琐碎和自动的东西是根本不可能的。嗯,不。你只需要将字符串标记为Unicode字符串。你永远不必使用locale来获得正确的大小写行为,除了f或者突厥语,这无论如何都不会有帮助。@tchrist-我分析了它不是Unicode,这就是为什么使用区域设置。Perl不理解Unicode区域设置的概念,如果不是,为什么强制使用Unicode,正则表达式的性能不会因此而降低?在内部,它可能是8位编码与字符语义的混合,但我虽然Unicode支持开销降低了速度。而且啊,我不确定PHP支持什么级别的Unicode。那么,你认为速度高于正确性,是吗?总是先将传统编码标准化为Unicode。无论如何,Perl在排序模块中支持Unicode区域设置。当然,这不在正则表达式中,甚至不在大小写中。大小写不支持ed是基于区域设置的。@tchrist-感谢您提供的提示!仅链接的建议值很低,应作为问题下的注释编写。
Form is s///  find and replace

s/                  # Search

  (?:                  # Group
      ^                   # beginning of string
    | (?<=\s)             # or, lookbehind \s
    | (?<=\w-)            # or, lookbehind \w-
    | (?<=\w\.)           # or, lookbehind \w\.
    | (?<=\w\')           # or, lookbehind \w\'
  )                    # End group
  (\w)                 # Capture group 1, a single word char

/                   # Replace
  uc($1)               # Upercased word char from capt grp 1

/xeg;               # Modifiers x(expanded), e(eval), g(global)
function mb_ucwords ($string)
{
    return mb_convert_case ($string, MB_CASE_TITLE, 'UTF-8'); 
}