Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to count the first 30 letters in a string ignoring spaces

Tags:

php

I want to take a post description but only display the first, for example, 30 letters but ignore any tabs and spaces.

$msg = 'I only need the first, let us just say, 30 characters; for the time being.';
$msg .= ' Now I need to remove the spaces out of the checking.';

$amount = 30;

// if tabs or spaces exist, alter the amount
if(preg_match("/\s/", $msg)) {
    $stripped_amount = strlen(str_replace(' ', '', $msg));
    $amount = $amount + (strlen($msg) - $stripped_amount);
}

echo substr($msg, 0, $amount);
echo '<br /> <br />';
echo substr(str_replace(' ', '', $msg), 0, 30);

The first output gives me 'I only need the first, let us just say, 30 characters;' and the second output gives me: Ionlyneedthefirst,letusjustsay so I know this isn't working as expected.

My desired output in this case would be:

I only need the first, let us just say

Thanks in advance, my maths sucks.

like image 553
Jaquarh Avatar asked Nov 17 '16 20:11

Jaquarh


2 Answers

You could get the part with the first 30 characters with a regular expression:

$msg_short = preg_replace('/^((\s*\S\s*){0,30}).*/s', '$1', $msg);

With the given $msg value, you will get in $msg_short:

I only need the first, let us just say

Explanation of the regular expression

  • ^: match must start at the beginning of the string
  • \s*\S\s* a non-white-space (\S) surrounded by zero or more white-space characters (\s*)
  • (\s*\S\s*){0,30} repeat finding this sequence up to 30 times (greedy; get as many as possible within that limit)
  • ((\s*\S\s*){0,30}) the parentheses make this series of characters group number 1, which can be referenced as $1
  • .* any other characters. This will match all remaining characters, because of the s modifier at the end:
  • s: makes the dot match new line characters as well

In the replacement only the characters are maintained that belong to group one ($1). All the rest is ignored and not included in the returned string.

like image 78
trincot Avatar answered Nov 04 '22 20:11

trincot


Spontaneously, there are two ways to achieve that I can think of.

The first one is close to what you did already. Take the first 30 characters, count the spaces and take as many next characters as you found spaces until the new set of letters has no spaces in it anymore.

$msg = 'I only need the first, let us just say, 30 characters; for the time being.';
$msg .= ' Now I need to remove the spaces out of the checking.';
$amount = 30;
$offset = 0;
$final_string = '';
while ($amount > 0) {
  $tmp_string = substr($msg, $offset, $amount);
  $amount -= strlen(str_replace(' ', '', $tmp_string));
  $offset += strlen($tmp_string);
  $final_string .= $tmp_string;
}
print $final_string;

The second technique would be to explode your string at spaces and put them back together one by one until you hit your threshold (where you would eventually need to break down a single word into characters).

like image 42
Paul Avatar answered Nov 04 '22 18:11

Paul