转换字符串但将字符用大括号括起来
Converting string but leave characters wrapped in braces
- 我正在转换用户输入的字符串(成功但是...)
- 我想忽略用大括号包裹的字符
- 也去掉最终输出中的大括号
例如,如果我有这个字符串:
$string = "[ABC] This & Text";
function make_post_type($string) {
$needle = array('-', ' ');
$clean = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($string)); // Remove special characters
$haystack = preg_replace('!\s+!', ' ', $clean); // Now remove extra spaces
return str_replace($needle, '_', $haystack);
}
returns abc_this_text
我愿意returnABC_this_text
一种解决方案是将字符串拆分为单词数组。
如果这个词包含 []
只删除它们,否则用特殊字符和 strtolower 做所有其他的事情。
然后内爆回到字符串 return
$string = "[ABC] This & Text";
Echo make_post_type($string);
function make_post_type($string) {
$needle = array('-', ' ');
$arr = explode(" ", $string);
foreach($arr as &$a){
if($a[0] != "[" && $a[-1] != "]"){
$a = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($a)); // Remove special characters
}else{
$a = substr($a, 1,-1);
}
}
$string = preg_replace('!\s+!', ' ', implode(" ", $arr)); // Now remove extra spaces
return str_replace($needle, '_', $string);
}
您可以在 preg_replace_callback
:
中使用此正则表达式代码
function replc($str) {
return preg_replace_callback (
'/\[([^]]*)\]|{([^}]*)}|([^][{}]+)/',
function ($m) {
return (isset($m[1])?$m[1]:"") .
(isset($m[2])?$m[2]:"") .
(isset($m[3]) ?
preg_replace('/\W+/', '_', strtolower($m[3])) : "");
},
$str
);
}
称其为:
echo replc( "[ABC] This & Text" );
ABC_this_text
echo replc( "abc.Xyz {PQR} Foo-Bar [ABC] This & Text" );
abc_xyz_PQR_foo_bar_ABC_this_text
第一个 RegEx 详细信息:
[([^]]*)\]
:如果我们遇到[...]
,则在组#1 中捕获内部部分
|
: 或
{([^}]*)}
:如果我们遇到{...}
,那么在组#2 中捕获内部部分
|
: 或
[^][{}]+
:匹配 1+ 个不是 [
和 ]
和 {
和 }
的字符并捕获到组 #3
第二个正则表达式:
\W+
:匹配1+个非单词字符被_
替换
您可以使用 preg_match_all 并使用 2 个捕获组。
\[([A-Z]+)\]|(\w+)
使用 array_reduce 按索引检查捕获组,最后使用下划线内爆:
例如:
$re = '/\[([A-Z]+)\]|(\w+)/';
$string = "[ABC] This & Text";
preg_match_all($re, $string, $matches, PREG_SET_ORDER, 0);
echo implode('_', array_reduce($matches, function($carry, $item){
if ($item[1] === "") {
$carry[] = strtolower($item[2]);
return $carry;
}
$carry[] = $item[1];
return $carry;
})); //ABC_this_text
说明
\[([A-Z]+)\]
匹配[
,捕获一组中的1+个大写字符并匹配]
。要匹配括号之间的所有内容,您可以改用 \[([^]]+)\]
。
|
或
(\w+)
抓取一组1+字字符。如果你想匹配超过 \w
你可以使用字符 class 并添加你想要匹配的内容,例如 [\w!?]+
您可以通过以另一种方式查看问题来减少生成所需字符串的步骤。首先匹配您需要的内容,然后在末尾用 _
替换空格和破折号:
function make_post_type($s) {
preg_match_all("~({[^{}]*}|\[[^][]*])|[\w\s]+~", $s, $m);
$s = '';
foreach($m[0] as $k => $v) {
$s .= $m[1][$k] ? substr($v, 1, -1) : strtolower($v);
}
return preg_replace('~[-\s]+~', '_', $s);
}
我将 {[^{}]*}|\[[^][]*]
括在括号中,以便稍后检查 (bool) $m[1][$k]
,它告诉 $m[1]
返回的捕获组中是否存在迭代中的当前值,然后去掉一个前导和字符串的尾随字符。
- 我正在转换用户输入的字符串(成功但是...)
- 我想忽略用大括号包裹的字符
- 也去掉最终输出中的大括号
例如,如果我有这个字符串:
$string = "[ABC] This & Text";
function make_post_type($string) {
$needle = array('-', ' ');
$clean = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($string)); // Remove special characters
$haystack = preg_replace('!\s+!', ' ', $clean); // Now remove extra spaces
return str_replace($needle, '_', $haystack);
}
returns abc_this_text
我愿意returnABC_this_text
一种解决方案是将字符串拆分为单词数组。
如果这个词包含 []
只删除它们,否则用特殊字符和 strtolower 做所有其他的事情。
然后内爆回到字符串 return
$string = "[ABC] This & Text";
Echo make_post_type($string);
function make_post_type($string) {
$needle = array('-', ' ');
$arr = explode(" ", $string);
foreach($arr as &$a){
if($a[0] != "[" && $a[-1] != "]"){
$a = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($a)); // Remove special characters
}else{
$a = substr($a, 1,-1);
}
}
$string = preg_replace('!\s+!', ' ', implode(" ", $arr)); // Now remove extra spaces
return str_replace($needle, '_', $string);
}
您可以在 preg_replace_callback
:
function replc($str) {
return preg_replace_callback (
'/\[([^]]*)\]|{([^}]*)}|([^][{}]+)/',
function ($m) {
return (isset($m[1])?$m[1]:"") .
(isset($m[2])?$m[2]:"") .
(isset($m[3]) ?
preg_replace('/\W+/', '_', strtolower($m[3])) : "");
},
$str
);
}
称其为:
echo replc( "[ABC] This & Text" );
ABC_this_text
echo replc( "abc.Xyz {PQR} Foo-Bar [ABC] This & Text" );
abc_xyz_PQR_foo_bar_ABC_this_text
第一个 RegEx 详细信息:
[([^]]*)\]
:如果我们遇到[...]
,则在组#1 中捕获内部部分
|
: 或{([^}]*)}
:如果我们遇到{...}
,那么在组#2 中捕获内部部分
|
: 或[^][{}]+
:匹配 1+ 个不是[
和]
和{
和}
的字符并捕获到组 #3
第二个正则表达式:
\W+
:匹配1+个非单词字符被_
替换
您可以使用 preg_match_all 并使用 2 个捕获组。
\[([A-Z]+)\]|(\w+)
使用 array_reduce 按索引检查捕获组,最后使用下划线内爆:
例如:
$re = '/\[([A-Z]+)\]|(\w+)/';
$string = "[ABC] This & Text";
preg_match_all($re, $string, $matches, PREG_SET_ORDER, 0);
echo implode('_', array_reduce($matches, function($carry, $item){
if ($item[1] === "") {
$carry[] = strtolower($item[2]);
return $carry;
}
$carry[] = $item[1];
return $carry;
})); //ABC_this_text
说明
\[([A-Z]+)\]
匹配[
,捕获一组中的1+个大写字符并匹配]
。要匹配括号之间的所有内容,您可以改用\[([^]]+)\]
。|
或(\w+)
抓取一组1+字字符。如果你想匹配超过\w
你可以使用字符 class 并添加你想要匹配的内容,例如[\w!?]+
您可以通过以另一种方式查看问题来减少生成所需字符串的步骤。首先匹配您需要的内容,然后在末尾用 _
替换空格和破折号:
function make_post_type($s) {
preg_match_all("~({[^{}]*}|\[[^][]*])|[\w\s]+~", $s, $m);
$s = '';
foreach($m[0] as $k => $v) {
$s .= $m[1][$k] ? substr($v, 1, -1) : strtolower($v);
}
return preg_replace('~[-\s]+~', '_', $s);
}
我将 {[^{}]*}|\[[^][]*]
括在括号中,以便稍后检查 (bool) $m[1][$k]
,它告诉 $m[1]
返回的捕获组中是否存在迭代中的当前值,然后去掉一个前导和字符串的尾随字符。