目标是从字符串 $a="NewYork"
中获取位于大写之前的没有小写的新字符串。
在这个例子中,我们应该得到输出“NeYork”
我试图通过 ASCII 表中大小字母的位置来做到这一点,但它不起作用。我不确定是否可以通过 ASCII 表中的位置以类似的方式执行此操作。
function delete_char($a)
{
global $b;
$a = 'NewYork';
for($i =0; $i<strlen($a); $i++)
{
if( ord($a[$i])< ord($a[$i+1])){//this solves only part of a problem
chop($a,'$a[$i]');
}
else{
$b.=$a[$i];
}
}
return $b;
}
答案 0 :(得分:2)
这是一个正则表达式很容易处理的东西
<?php
$a ="NewYorkNewYork";
$reg="/[a-z]([A-Z])/";
echo preg_replace($reg, "$1", $a); // NeYorNeYork
正则表达式搜索一个小写字母后跟一个大写字母,并捕获大写字母。 preg_replace()
然后仅用捕获的字母 ($1
) 替换该组合。
答案 1 :(得分:2)
您不需要捕获大写字母并在替换字符串中使用反向引用。
更简单地,匹配小写字母然后对大写字母使用前瞻——这样您只需用空字符串替换小写字符。 (Demo)
echo preg_replace('~[a-z](?=[A-Z])~', '', 'NewYork');
// NeYork
至于对代码的审查,存在多个问题。
global $b
对我来说没有意义。您只需要在自定义函数的范围内将变量实例化为空字符串。更简单的应该是 $b = '';
。
变量和函数命名没有帮助。函数的名称应具体描述函数的操作。变量应该直观地描述它包含的数据。一般来说,不要为了简洁而牺牲清晰度。
作为最佳实践,当您知道值没有改变时,不应重复调用函数。在循环的每次迭代中调用 strlen()
是没有好处的。反复声明 $length = strlen($input)
并使用 $length
。
$a[$i+1]
将在循环的最后一次迭代中生成未定义的偏移警告,因为当您已经知道字符串的长度已被完全处理时,该偏移处不可能有字符。换句话说,字符串的最后一个字符的偏移量为“length - 1”。解决这个问题的方法不止一种,但我将使用空合并运算符来设置一个回退字符,该字符将不符合要删除的前一个字母的条件。
最重要的是,您不能只检查当前 ord 值是否小于下一个 ord 值。请参阅 here 小写字母的序数范围为 97 到 122,大写字母的序数范围为 65 到 90。您需要检查这两个字母是否符合当前字母包含在结果字符串。
重写:(Demo)
function removeLowerCharBeforeUpperChar(string $input): string
{
$output = '';
$length = strlen($input);
for ($offset = 0; $offset < $length; ++$offset) {
$currentOrd = ord($input[$offset]);
$nextOrd = ord($input[$offset + 1] ?? '_');
if ($currentOrd < 97
|| $currentOrd > 122
|| $nextOrd < 65
|| $nextOrd > 90
){
$output .= $input[$offset];
}
}
return $output;
}
echo removeLowerCharBeforeUpperChar('MickMacKusa');
// MicMaKusa
或使用 ctype_
函数:(Demo)
function removeLowerCharBeforeUpperChar(string $input): string
{
$output = '';
$length = strlen($input);
for ($offset = 0; $offset < $length; ++$offset) {
$nextLetter = $input[$offset + 1] ?? '';
if (ctype_lower($input[$offset]) && ctype_upper($nextLetter)) {
$output .= $nextLetter; // omit current letter, save next
++$offset; // double iterate
} else {
$output .= $input[$offset]; // save current letter
}
}
return $output;
}
澄清一下,我不会在专业脚本中使用上述自定义函数,并且这两个代码段都不是为处理包含多字节字符的字符串而构建的。
答案 2 :(得分:1)
简单地说,我创建了一个新变量 $s
用于存储要返回的新字符串和一个 make 循环迭代 $a
字符串,我使用 ctype_upper 来检查下一个字符是否不是大写追加到 $s
。最后我返回 $s
与字符串的最后一个字符连接。
function delete_char(string $a): string
{
if(!strlen($a))
{
return '';
}
$s='';
for($i = 0; $i < strlen($a)-1; $i++)
{
if(!ctype_upper($a[$i+1])){
$s.=$a[$i];
}
}
return $s.$a[-1];
}
echo delete_char("NewYork");//NeYork
答案 3 :(得分:-1)
可能是这样的吗?
<?php
$word = 'NewYork';
preg_match('/.[A-Z].*/', $word, $match);
if($match){
$rlen = strlen($match[0]); //length from character before capital letter
$start = strlen($word)-$rlen; //first lower case before the capital
$edited_word = substr_replace($word, '', $start, 1); //removes character
echo $edited_word; //prints NeYork
}
?>