跳过缩写时将驼峰式大小写格式化为在 PHP 中可读
Formatting camel case to readable in PHP while skipping abbreviations
所以我被卡住了 - 我在这里看了很多答案,但 none 似乎解决了我的最后一个问题。
通过 API 和 JSON,我收到了驼峰格式的设备列表。我无法改变这一点。
我需要将驼峰命名法翻译成普通语言 -
到目前为止,我得到的大部分单词都是通过以下方式分隔的:
$string = "SomeEquipmentHere";
$spaced = preg_replace('/([A-Z])/', ' ', $string);
var_dump($spaced);
string ' Some Equipment Here' (length=20)
$trimmed = trim($spaced);
var_dump($trimmed);
string 'Some Equipment Here' (length=19)
哪个工作正常 - 但在某些设备中包含缩写
"ABSBrakes" - 这需要 ABS 并与刹车分开
我无法检查彼此相邻的几个大写字母,因为它会将 ABS 和 Brakes 放在一起 - 还有更多类似的,即:"CDRadio"
所以想要的是输出:
"ABS Brakes"
有没有办法格式化它,如果大写字母彼此相邻,则只在该序列的最后一个大写字母前添加 space?
我不擅长正则表达式。
编辑
两个贡献都很棒 - 以后来这里的人应该阅读两个答案
最后要解决的问题是以下模式:
"ServiceOK" 变为 "Service O K"
"ESP" 变为 "ES P"
只由纯大写缩写组成的模式由一个计算小写字母的函数固定,如果有none,它将跳过preg_replace()。
但是正如 Flying 在他的回答的评论中所写的那样,他的正则表达式可能没有涵盖很多实例,并且答案可能是不可能的 - 我不知道这是否对正则表达式。
可能通过添加一些 "If there is not a lowercase after the uppercase, there should not be inserted a space" 规则
解决方法如下:
$tests = [
'SomeEquipmentHere',
'ABSBrakes',
'CDRadio',
'Valve14',
];
foreach ($tests as $test) {
echo trim(preg_replace('/\s+/', ' ', preg_replace('/([A-Z][a-z]+)|([A-Z]+(?=[A-Z]))|(\d+)/', ' ', $test)));
echo "\n";
}
相关测试 regex101。
更新:为其他问题添加示例
这是一个在替换字符串中不使用任何锚点、捕获组或引用的单一调用模式:/(?:[a-z]|[A-Z]+)\K(?=[A-Z]|\d+)/
代码:(Demo)
$tests = [
'SomeEquipmentHere',
'ABSBrakes',
'CDRadio',
'Valve14',
];
foreach ($tests as $test) {
echo preg_replace('/(?:[a-z]|[A-Z]+)\K(?=[A-Z]|\d+)/',' ',$test),"\n";
}
输出:
Some Equipment Here
ABS Brakes
CD Radio
Valve 14
这是一个更好的方法,因为没有什么可以擦掉的。如果有新的字符串需要考虑(破坏我的方法),请将它们留在评论中,以便我可以更新我的模式。
图案说明:
/ #start the pattern
(?:[a-z] #match 1 lowercase letter
| #or
[A-Z]+) #1 or more uppercase letters
\K #restart the fullstring match (forget the past)
(?=[A-Z] #look-ahead for 1 uppercase letter
| #or
\d+) #1 or more digits
/ #end the pattern
编辑:
还有一些其他模式可以提供更好的准确性,包括:
/(?:[a-z]|\B[A-Z]+)\K(?=[A-Z]\B|\d+)/
当然,上述模式无法正确处理 ServiceOK
Demo Link Word Boundaries Link
或者这个带有锚点的模式:
/(?!^)(?=[A-Z][a-z]+|(?<=\D)\d)/
以上模式将根据以下要求准确拆分:SomeEquipmentHere
、ABSBrakes
、CDRadio
、Valve14
、ServiceOK
、ESP
OP.
*注意:随着提供更多示例字符串,可以提高模式准确性。
所以我被卡住了 - 我在这里看了很多答案,但 none 似乎解决了我的最后一个问题。
通过 API 和 JSON,我收到了驼峰格式的设备列表。我无法改变这一点。
我需要将驼峰命名法翻译成普通语言 -
到目前为止,我得到的大部分单词都是通过以下方式分隔的:
$string = "SomeEquipmentHere";
$spaced = preg_replace('/([A-Z])/', ' ', $string);
var_dump($spaced);
string ' Some Equipment Here' (length=20)
$trimmed = trim($spaced);
var_dump($trimmed);
string 'Some Equipment Here' (length=19)
哪个工作正常 - 但在某些设备中包含缩写
"ABSBrakes" - 这需要 ABS 并与刹车分开
我无法检查彼此相邻的几个大写字母,因为它会将 ABS 和 Brakes 放在一起 - 还有更多类似的,即:"CDRadio"
所以想要的是输出:
"ABS Brakes"
有没有办法格式化它,如果大写字母彼此相邻,则只在该序列的最后一个大写字母前添加 space?
我不擅长正则表达式。
编辑
两个贡献都很棒 - 以后来这里的人应该阅读两个答案
最后要解决的问题是以下模式:
"ServiceOK" 变为 "Service O K"
"ESP" 变为 "ES P"
只由纯大写缩写组成的模式由一个计算小写字母的函数固定,如果有none,它将跳过preg_replace()。
但是正如 Flying 在他的回答的评论中所写的那样,他的正则表达式可能没有涵盖很多实例,并且答案可能是不可能的 - 我不知道这是否对正则表达式。
可能通过添加一些 "If there is not a lowercase after the uppercase, there should not be inserted a space" 规则
解决方法如下:
$tests = [
'SomeEquipmentHere',
'ABSBrakes',
'CDRadio',
'Valve14',
];
foreach ($tests as $test) {
echo trim(preg_replace('/\s+/', ' ', preg_replace('/([A-Z][a-z]+)|([A-Z]+(?=[A-Z]))|(\d+)/', ' ', $test)));
echo "\n";
}
相关测试 regex101。
更新:为其他问题添加示例
这是一个在替换字符串中不使用任何锚点、捕获组或引用的单一调用模式:/(?:[a-z]|[A-Z]+)\K(?=[A-Z]|\d+)/
代码:(Demo)
$tests = [
'SomeEquipmentHere',
'ABSBrakes',
'CDRadio',
'Valve14',
];
foreach ($tests as $test) {
echo preg_replace('/(?:[a-z]|[A-Z]+)\K(?=[A-Z]|\d+)/',' ',$test),"\n";
}
输出:
Some Equipment Here
ABS Brakes
CD Radio
Valve 14
这是一个更好的方法,因为没有什么可以擦掉的。如果有新的字符串需要考虑(破坏我的方法),请将它们留在评论中,以便我可以更新我的模式。
图案说明:
/ #start the pattern
(?:[a-z] #match 1 lowercase letter
| #or
[A-Z]+) #1 or more uppercase letters
\K #restart the fullstring match (forget the past)
(?=[A-Z] #look-ahead for 1 uppercase letter
| #or
\d+) #1 or more digits
/ #end the pattern
编辑:
还有一些其他模式可以提供更好的准确性,包括:
/(?:[a-z]|\B[A-Z]+)\K(?=[A-Z]\B|\d+)/
当然,上述模式无法正确处理 ServiceOK
Demo Link Word Boundaries Link
或者这个带有锚点的模式:
/(?!^)(?=[A-Z][a-z]+|(?<=\D)\d)/
以上模式将根据以下要求准确拆分:SomeEquipmentHere
、ABSBrakes
、CDRadio
、Valve14
、ServiceOK
、ESP
OP.
*注意:随着提供更多示例字符串,可以提高模式准确性。