如果后跟大写字母,则删除小写字母

时间:2021-04-02 13:16:43

标签: php string ascii lowercase

目标是从字符串 $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;
}

4 个答案:

答案 0 :(得分:2)

这是一个正则表达式很容易处理的东西

<?php

$a ="NewYorkNewYork";
$reg="/[a-z]([A-Z])/";
echo preg_replace($reg, "$1", $a); // NeYorNeYork


正则表达式搜索一个小写字母后跟一个大写字母,并捕获大写字母。 preg_replace() 然后仅用捕获的字母 ($1) 替换该组合。

https://3v4l.org/o43bO

答案 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
    }
?>