我正在尝试修复一些手动输入的地址。我需要在整个地址上应用ucwords
,但我希望将所有罗马数字保留为大写字母,并将字母保留在门牌号码后面。
VIA PIPPO III 74A
应该成为:
Via Pippo III 74A
我怎样才能做到这一点?
答案 0 :(得分:2)
使用negative lookahead查找不罗马数字的字词:
/\b(?![LXIVCDM]+\b)([A-Z]+)\b/
说明:
\b
- 在字边界处断言位置(?!
- 负向前瞻
[LXIVCDM]+
- 匹配列表中的任何字符一次或多次\b
- 在字边界处断言位置)
- 结束否定前瞻[A-Z]
- 任何大写字母,一次或多次\b
- 在字边界处断言位置实际上,这匹配任何不是完全的单词由列表[LXIVCDM]
中的字符组成 - 也就是说,它匹配任何不是罗马数字的单词。
现在,使用preg_replace_callback()
捕获这些单词,将它们转换为小写,然后将第一个字母大写:
$input = 'VIA PIPPO III 74A';
$pattern = '/\b(?![LXIVCDM]+\b)([A-Z]+)\b/';
$output = preg_replace_callback($pattern, function($matches) {
return ucfirst(strtolower($matches[0]));
}, $input);
var_dump($output);
输出:
string(17) "Via Pippo III 74A"
答案 1 :(得分:0)
$str = mb_eregi_replace('\b([0-9]{1,4}[a-z]{1,2})\b', "strtoupper('\\1')", $str, 'e');
完整示例,如何修复手动输入的地址,大写字母的第一个字母并保留大写罗马数字和字母A后面的字母A,B,C):
function ucAddress($str) {
// first lowercase all and use the default ucwords
$str = ucwords(strtolower($str));
// let's fix the default ucwords...
// uppercase letters after house number (was lowercased by the strtolower above)
$str = mb_eregi_replace('\b([0-9]{1,4}[a-z]{1,2})\b', "strtoupper('\\1')", $str, 'e');
// the same for roman numerals
$str = mb_eregi_replace('\bM{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b', "strtoupper('\\0')", $str, 'e');
return $str;
}