[英]Using preg_replace() to convert CamelCase to 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()
调用减少到一行,这将给我相同的结果。 有任何想法吗?
注意: 参考这篇文章 ,我的研究向我展示了一个preg_replace()
正则表达式,它几乎得到了我想要的结果,除了它不能用于将foo123
转换为foo-123
的例子。
你可以使用lookarounds在一个正则表达式中完成所有这些:
function camelToUnderscore($string, $us = "-") {
return strtolower(preg_replace(
'/(?<=\d)(?=[A-Za-z])|(?<=[A-Za-z])(?=\d)|(?<=[a-z])(?=[A-Z])/', $us, $string));
}
RegEx说明:
(?<=\d)(?=[A-Za-z]) # if previous position has a digit and next has a letter
| # OR
(?<=[A-Za-z])(?=\d) # if previous position has a letter and next has a digit
| # OR
(?<=[a-z])(?=[A-Z]) # if previous position has a lowercase and next has a uppercase letter
这是我基于我之前标记的重复帖子的两分钱。 这里接受的解决方案很棒。 我只想尝试用共享内容来解决它:
function camelToUnderscore($string, $us = "-") {
return strtolower(preg_replace('/(?<!^)[A-Z]+|(?<!^|\d)[\d]+/', $us.'$0', $string));
}
示例:
Array
(
[0] => foo
[1] => fooBar
[2] => foo123
[3] => 123Foo
[4] => fooBar123
[5] => foo123Bar
[6] => 123FooBar
)
foreach ($arr as $item) {
echo camelToUnderscore($item);
echo "\r\n";
}
输出:
foo foo-bar foo-123 123-foo foo-bar-123 foo-123-bar 123-foo-bar
说明:
(?<!^)[A-Z]+ // Match one or more Capital letter not at start of the string
| // OR
(?<!^|\d)[\d]+ // Match one or more digit not at start of the string
$us.'$0' // Substitute the matching pattern(s)
问题已经解决,所以我不会说我希望它有所帮助,但也许有人会觉得这很有用。
编辑
这个正则表达式有限制:
foo123bar => foo-123bar
fooBARFoo => foo-barfoo
感谢@urban指出。 以下是他在此问题上发布的三个解决方案的测试链接:
来自同事:
$string = preg_replace(array($pattern1, $pattern2), $us.'$1', $string);
可能有用
我的解决方案
public function camelToUnderscore($string, $us = "-")
{
$patterns = [
'/([a-z]+)([0-9]+)/i',
'/([a-z]+)([A-Z]+)/',
'/([0-9]+)([a-z]+)/i'
];
$string = preg_replace($patterns, '$1'.$us.'$2', $string);
// Lowercase
$string = strtolower($string);
return $string;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.