我如何 return 字符串的其余部分?

How do i return the remainder of a string?

我在字符串中有一些文本,我想将其分成两半,但在一个完整的单词后它会中断。

$text = "This is a string of test text";

我用的 substr() 很棒,但是把一个词减半了。

substr($text, 0, 15);

resulted in outputting: "This is a strin"

所以我找到并尝试了这种方法:

$part1=$text;
if (preg_match('/^.{1,15}\b/s', $text, $match))
{
  $part1=$match[0];
}

这给了我“这是一个”

完美!

...但是如何在另一个变量中获取“测试文本字符串”?

它很懒,但是因为你有第 1 部分,所以你可以像这样获得第 2 部分:

$part1=$text;
if (preg_match('/^.{1,15}\b/s', $text, $match))
{
  $part1=$match[0];
}
$part2 = str_replace($part1, "", $text);

它从字符串中删除了第 1 部分,因此您将得到第 2 部分

更好的解决方案(但有点难)是通过在 preg_match 方法中捕获偏移量来获取第 2 部分的索引。它为您提供匹配字符串的位置:

$part1=$text;
if (preg_match('/^.{1,15}\b/s', $text, $match, PREG_OFFSET_CAPTURE))
{
  $part1 = $match[0][0];
  $part2 = substr($text, $match[0][1] + strlen($part1), strlen($text) - strlen($part1));
}

第二个解决方案可能需要一些修正。

使用 wordwrap 将使用换行符换行,默认情况下不剪切单词:

$text = wordwrap($text, 15);

产量:

This is a
string of test
text

您可以使用该字符串或将每一行作为数组元素获取:

$lines = explode("\n", $text);

然后您可以单独使用它们,或者如果您只想要第一部分然后再使用其余部分:

$first = array_shift($lines);
$remaining = implode(" ", $lines);

至于正则表达式,使用捕获组 () 获取第一部分和剩余部分:

preg_match('/^(.{1,15}\b)(.*)/s', $text, $match);

0 中产生完整匹配,然后在 12 中产生捕获组:

Array
(
    [0] => This is a string of test text
    [1] => This is a 
    [2] => string of test text
)

首先我不同意字符串This is a完美的说法,纯粹是基于子串长度是总弦长的三分之一,如果你在 string 之后断开,你可以更接近 中间 ?

This is a           ==> 9
string of test text ==> 19

This is a string  ==> 16
of test text      ==> 13

因此,考虑到这一点,我将使用以下内容:

// String to split in ~half
$text = "This is a string of test text";

// Set initial lengths to the half way point of the string, rounding down
$max = $min = $length = floor(strlen($text) / 2);

// Loop through a maximum of `half total string length` times
//   > Half because we're doubling the count by [inc/dec]rementing
//     $min and $max on each loop
for($i = 0; $i < $length; $i++){

    // Create the pattern; using sprintf so it's a bit easier to read
    // We're also post [inc/dec]rementing the variables $min and $max
    $pattern = sprintf('/^(.{%d,%d})\b(.*)$/', $min--, $max++);
    
    // Check to see if there was a match
    if( preg_match($pattern, $text, $matches) ){
        break;
    }

    // If no match by the end of the loop set matches to FALSE
    // This would happen if, for example, there were no boundaries (\b)
    $matches = FALSE;
}

// Code without comments...

for($i = 0; $i < $length; $i++){
    $pattern = sprintf('/^(.{%d,%d})\b(.*)$/', $min--, $max++);
    if( preg_match($pattern, $text, $matches) )
        break;
    $matches = FALSE;
}

迭代模式

匹配项,在本例中是在第三个循环中找到的...

/^(.{14,14})\b(.*)$/
/^(.{13,15})\b(.*)$/
/^(.{12,16})\b(.*)$/

输出

array(3) {
  [0]=>
  string(29) "This is a string of test text"
  [1]=>
  string(16) "This is a string"
  [2]=>
  string(13) " of test text"
}