我现在有一个方法可以将camel case字符串转换为snake case字符串,但它被分解为三个preg_replace()
调用:
public function camelToUnderscore($string, $us = "-")
{
// insert hyphen between any letter and the beginning of a numeric chain
$string = preg_replace('/([a-z]+)([0-9]+)/i', '$1'.$us.'$2', $string);
// insert hyphen between any lower-to-upper-case letter chain
$string = preg_replace('/([a-z]+)([A-Z]+)/', '$1'.$us.'$2', $string);
// insert hyphen between the end of a numeric chain and the beginning of an alpha chain
$string = preg_replace('/([0-9]+)([a-z]+)/i', '$1'.$us.'$2', $string);
// Lowercase
$string = strtolower($string);
return $string;
}
我编写了测试来验证它的准确性,它可以在以下输入数组(array('input' => 'output')
)中正常工作:
$test_values = [
'foo' => 'foo',
'fooBar' => 'foo-bar',
'foo123' => 'foo-123',
'123Foo' => '123-foo',
'fooBar123' => 'foo-bar-123',
'foo123Bar' => 'foo-123-bar',
'123FooBar' => '123-foo-bar',
];
我想知道是否有一种方法可以将我的preg_replace()
调用减少到一行,这将给予我同样的结果。
注意:Referring to this post,我的研究已经向我展示了一个preg_replace()
正则表达式,它几乎可以得到我想要的结果,除了它不能在foo123
的例子中将其转换为foo-123
。
4条答案
按热度按时间eit6fx6z1#
您可以使用lookarounds在单个正则表达式中完成所有这些操作:
RegEx Demo
Code Demo
注册表描述:
35g0bw712#
以下是我根据之前标记的重复帖子得出的两点意见。这里的公认解决方案非常棒。我只是想尝试用分享的内容来解决它:
示例:
输出:
说明:
online regex
这个问题已经解决了,所以我不会说我希望它有帮助,但也许有人会发现这有用。
编辑
此正则表达式存在一些限制:
感谢@urban指出这一点。下面是他在这个问题上发布的三个解决方案的测试链接:
three solutions demo
k4emjkb13#
来自同事:
$string = preg_replace(array($pattern1, $pattern2), $us.'$1', $string);
可能有效我的解决方案:
dbf7pr2w4#
您不需要承受大量的查找或多组模式来定位单词或连续数字之间的位置的低效性。
使用贪婪匹配来查找所需的序列,然后用
\K
重置全字符串匹配,然后检查该位置是否是字符串的结尾。所有符合条件的字符都应该接收分隔符。这种贪婪模式的速度在于它消耗一个或多个序列,并且从不回头。我将在答案中省略
strtolower()
调用,因为它只是挑战的干扰。代码:(Demo)
字/数间处理:
| 用户|台阶|模式|置换|
| - ------|- ------|- ------|- ------|
| 阿努巴瓦|660|
/(?<=\d)(?=[A-Za-z])|(?<=[A-Za-z])(?=\d)|(?<=[a-z])(?=[A-Z])
|'-'
|| 米克马库萨|337|
/(?:\d++|[A-Za-z]?[a-z]++)\K(?!$)/
|'-'
|严格的CamelCase处理:
| 用户|台阶|模式|置换|
| - ------|- ------|- ------|- ------|
| 爵士乐|321|
/(?<!^)[A-Z]+|(?<!^|\d)[\d]+/
|'-$0'
|| 米克马库萨|250|
/(?>\d+|[A-Z][a-z]*|[a-z]+)(?!$)/
|'$0-'
|| 米克马库萨|244|
/(?:\d++|[a-z]++)\K(?!$)/
|x1米11米1x|我对“马特”的答案打了折扣,因为它在每根弦上都有三次完整的传球--就效率而言,它甚至不在同一个球场上。