子字符串最多 25 个字符,如果与模式匹配,则保留字符串的末尾


substring max 25 chars keeping the end of string if match the pattern

我有一个字符串可以像这样:

$string = 'namestring';

或 $string = 'namestring_1';

名称字符串可以是所有内容,可以或不后跟下划线 + 数字。

我需要检查字符串长度是否超过 25 个字符,如果它被截断,则仅截断保留下划线+数字的名称字符串部分(如果有),因此总长度将为 25 个字符。

例:

$string ='012345678901234567890123456789_6';
$string2 ='012345678901234567890123456789';

必须换成:

$string ='01234567890123456789012_6';
$string2 ='0123456789012345678901234';

你能帮我吗?

编辑:不好意思。。。我没有想到指定它。不一定只有一个数字,即使下划线后面的两位数非常罕见。

来自山的丑陋正则表达式解决方案(下划线后仅 1 位数字):

$result = preg_replace('~^.{23}'K(?(?!.*_'d$)(.{2})).*(_'d)?$~', '$1$2', $str); 

图案细节:

我使用有条件的内部(如果...然后...): (?(?!.*_'d$)(.{2}))

(?             # IF
  (?!.*_'d$)   # (CONDITION): if there is not _'d at the end
  (.{2})       # THEN: capture two other characters
)              # ENDIF

或者更好的分支重置(?|..|..)

$result = preg_replace('~^'d{23}'K(?|.*(_'d)|(.{2}).*)$~', '$1', $str);
$string ='012345678901234567890123456789_6';
$string2 ='012345678901234567890123456789';
$string3 ='0123456_78901234567890123456789';
$c = explode("_", $string, 2);
$fixed = (count($c) > 1 ? (((strlen($c[0]) > 23) ? (substr($c[0],0,strlen($c[0]))) : substr((substr($c[0],0,23) . "_" . $c[1]),0,25))) : substr($c[0],0,25));

无论输入是什么,这都有效。

输出

  • 对于 $string = "01234567890123456789012_6"
  • 对于 $string 2 = "0123456789012345678901234"
  • 对于 $string 3 = "0123456_78901234567890123"

为什么不使用substr()?以下是我将如何做到这一点:

$str= "67676767676767676766767675757675757575757575746655_2";
$pos = strpos($str,"_");
$end = substr($str, $pos-strlen($str));
$start = substr($str, 25-strlen($pos));
$your_string = $start.$end;

编辑:在所有 4 个答案中,如果您在 _ :)后面有一个 2 位数字,只有我的答案可以工作

我认为如果

下划线后只能跟一个数字,这对您来说可能是一个可行的解决方案。 否则,您只需要修改它,使 23 变为 25 - strlen($match[1]) .

if (preg_match('/(_'d)$/', $namestring, $match)) {
    $namestring = substr(0, 23, $namestring) . $match[1];
} else {
    $namestring = substr(0, 25);
}