178

I want to extract the first word of a variable from a string. For example, take this input:

<?php $myvalue = 'Test me more'; ?>

The resultant output should be Test, which is the first word of the input. How can I do this?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
ali
  • 1,847
  • 2
  • 12
  • 10
  • You might find [`s($str)->words()[0]`](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L363) helpful, as found in [this standalone library](https://github.com/delight-im/PHP-Str). – caw Jul 27 '16 at 00:10
  • A small table of potential fringe cases when getting the substring before the first occurrence of a character: https://stackoverflow.com/a/68123370/2943403 – mickmackusa Aug 11 '21 at 04:46

17 Answers17

327

There is a string function (strtok) which can be used to split a string into smaller strings (tokens) based on some separator(s). For the purposes of this thread, the first word (defined as anything before the first space character) of Test me more can be obtained by tokenizing the string on the space character.

<?php
$value = "Test me more";
echo strtok($value, " "); // Test
?>

For more details and examples, see the strtok PHP manual page.

acme
  • 14,654
  • 7
  • 75
  • 109
salathe
  • 51,324
  • 12
  • 104
  • 132
  • 4
    Briliiant! Better than the original solution – Alberto Fontana Feb 13 '15 at 12:15
  • This should be the first answer. It only returns the first word like he wanted in a cleaner way. – Wes Oct 23 '17 at 15:34
  • 2
    Good solution but in the php manual, it warns: This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. – Jay Harris Nov 25 '17 at 22:29
  • 2
    I'm using PHP on a daily basis for at least 6 years and I didn't ever heard about this function until now – Epoc Dec 07 '17 at 14:21
  • 6
    `strtok` is a weird and dangerous function that holds a global state. Using this function should be discouraged. – Arnold Daniels Aug 19 '18 at 22:37
  • Doesn't work. try this with this string: "\n\nNextWord". This answer assumes all words are separate by spaces only. – Dev Null Jan 17 '21 at 18:43
290

You can use the explode function as follows:

$myvalue = 'Test me more';
$arr = explode(' ',trim($myvalue));
echo $arr[0]; // will print Test

Another example:

$sentence = 'Hello World this is PHP';
$abbreviation = explode(' ', trim($sentence ))[0];
echo $abbreviation // will print Hello
ecm
  • 2,583
  • 4
  • 21
  • 29
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • 52
    Using modern PHP syntax you can just do `explode(' ',trim($myvalue))[0]` – Elly Post Apr 01 '16 at 06:28
  • 3
    1 line code for any PHP version : `list($firstword) = explode(' ', trim($myvalue), 1);` – Cédric Françoys Oct 27 '16 at 10:33
  • 3
    @CédricFrançoys the `limit` parameter should be 2 since it has to include the last element that contains the rest of the string; 1 would just return the very same string. Unless a big array would be created I would go with Elliot version for a one liner. – Sdlion Feb 28 '17 at 00:13
  • What if you want the second word as well as from RSS [NewYorkTimes](http://rss.nytimes.com/services/xml/rss/nyt/Sports.xml) - media:credit is - Dmitry Kostyukov for The New York Times . I only want Dmitry Kostyukov - How do I do that? =) –  Apr 17 '17 at 11:23
  • @xxxx, do `explode(" ",strip_tags("Dmitry Kostyukov for The New York Times"))[0]` – pbarney Sep 06 '17 at 13:33
  • @j4k3 Please remember to [be nice](https://stackoverflow.com/help/be-nice). – Filnor Mar 05 '18 at 15:36
  • If you're looking for the most inefficient way to get the first word in a string, this is a good solution. In all other cases you're better off with literally every other answer here. How does this get any upvotes? – j4k3 Mar 05 '18 at 15:44
  • This is not the best answer! It echoes "one," if the string is "one, two three". The best answer is lower down, @Ciul – patrick Aug 17 '18 at 15:23
  • Doesn't work. try this with this string: "\n\nNextWord". This answer assumes all words are separate by spaces only. – Dev Null Jan 17 '21 at 18:42
  • Words do not end at the first space, but at the first character, that's not a letter. For eample `"Hey, how are you?` (returns "Hey,") or `Stop! Now` (returns "Stop!) – Philipp Apr 02 '21 at 19:34
45

If you have PHP 5.3

$myvalue = 'Test me more';
echo strstr($myvalue, ' ', true);

note that if $myvalue is a string with one word strstr doesn't return anything in this case. A solution could be to append a space to the test-string:

echo strstr( $myvalue . ' ', ' ', true );

That will always return the first word of the string, even if the string has just one word in it

The alternative is something like:

$i = strpos($myvalue, ' ');
echo $i !== false ? $myvalue : substr( $myvalue, 0, $i );

Or using explode, which has so many answers using it I won't bother pointing out how to do it.

patrick
  • 11,519
  • 8
  • 71
  • 80
Yacoby
  • 54,544
  • 15
  • 116
  • 120
  • 1
    +1 for not using explode or regex (both inappropriate imho). Another alternative would be to use strstr with str_replace, replacing the part after the needle from strstr with nothing. – Gordon Mar 19 '10 at 11:45
  • 1
    Worth noting, that although `strstr` is available in PHP since `4.3.0` it was not before `5.3.0`, when the optional parameter `before_needle` (which you're using in this example) was added. Just a notice, because I was confused, why you state, that this example needs `5.3.0`. – trejder May 07 '13 at 08:07
  • Note that if you set myvalue to a single word strstr doesn't return anything in this case! A solution could be to always add a space at the end of the string that's tested so it always comes back with the first word, even if that's the only word in the string! – patrick Dec 07 '15 at 00:44
  • 1
    Assuming only spaces between words is risky, I'd also include tabs. –  Jan 05 '16 at 23:03
  • 1
    shouldn't that be `echo $i === false ? $myvalue : substr( $myvalue, 0, $i );` – But those new buttons though.. Jun 13 '18 at 19:50
  • Doesn't work. try this with this string: "\n\nNextWord". This answer assumes all words are separate by spaces only. – Dev Null Jan 17 '21 at 18:43
24

You could do

echo current(explode(' ',$myvalue));
AntonioCS
  • 8,335
  • 18
  • 63
  • 92
15

Even though it is little late, but PHP has one better solution for this:

$words=str_word_count($myvalue, 1);
echo $words[0];
Olimpiu POP
  • 5,001
  • 4
  • 34
  • 49
7

Similar to accepted answer with one less step:

$my_value = 'Test me more';
$first_word = explode(' ',trim($my_value))[0];

//$first_word == 'Test'
wheelmaker
  • 2,975
  • 2
  • 21
  • 32
  • Doesn't work. try this with this string: "\n\nNextWord". This answer assumes all words are separate by spaces only. – Dev Null Jan 17 '21 at 18:44
  • yes, this does assume a "sentence" is constructed of words separated by spaces – wheelmaker Jan 17 '21 at 19:31
  • I think you missed the point. I upper-cased "W" in word so you could read it easier. Maybe this will make more sense to you - "\n\nThis won't work". The above code will think the first word is "\n\nThis" – Dev Null Mar 13 '21 at 23:24
  • This late, redundant, unexplained answer missed a great opportunity to limit the number of explosions. – mickmackusa Aug 11 '21 at 04:44
5

Just in case you are not sure the string starts with a word...

$input = ' Test me more ';
echo preg_replace('/(\s*)([^\s]*)(.*)/', '$2', $input); //Test
Lupuz
  • 121
  • 1
  • 6
  • 1
    `trim($input)` would suffice in this instance :P – zanderwar Jun 25 '15 at 07:39
  • I would not capture the `\s*`. I would not write `[^\s]` because `\S` is simpler. I would not capture the `.*` at the end. This answer is doing too many unnecessary things for a such a small snippet. – mickmackusa Aug 11 '21 at 04:24
4
$string = ' Test me more ';
preg_match('/\b\w+\b/i', $string, $result); // Test
echo $result;

/* You could use [a-zA-Z]+ instead of \w+ if wanted only alphabetical chars. */
$string = ' Test me more ';
preg_match('/\b[a-zA-Z]+\b/i', $string, $result); // Test
echo $result;

Regards, Ciul

Ciul
  • 633
  • 6
  • 7
  • 1
    This would be the best answer, since it also works for "one, two and three" (the accepted answer would echo "one,") – patrick Aug 17 '18 at 15:22
  • Why use `i` pattern modifier if the character class has `[a-zA-Z]` or if you are using `\w`? What should the output be if the first "word" contains an apostrophe or hyphen? Food for thought. This unexplained answer is teaching unnecessary things. – mickmackusa Aug 11 '21 at 04:25
4
<?php
  $value = "Hello world";
  $tokens = explode(" ", $value);
  echo $tokens[0];
?>

Just use explode to get every word of the input and output the first element of the resulting array.

Ulf
  • 17,492
  • 5
  • 19
  • 13
  • Doesn't work. try this with this string: "\n\nNextWord". This answer assumes all words are separate by spaces only. – Dev Null Jan 17 '21 at 18:45
  • This answer does not limit the number of explosions, so it is potentially doing more work than what is required. – mickmackusa Aug 11 '21 at 04:29
3

Using split function also you can get the first word from string.

<?php
$myvalue ="Test me more";
$result=split(" ",$myvalue);
echo $result[0];
?>
rekha_sri
  • 2,677
  • 1
  • 24
  • 27
  • 5
    NOTE- split() is DEPRECATED from 5.3 > – Leo Jun 03 '11 at 08:35
  • There is no limit to the `split()`, so this technique will be over-functioning. It only needs to explode on the first occurring space to do the job properly. – mickmackusa Aug 11 '21 at 04:26
3

personally strsplit / explode / strtok does not support word boundaries, so to get a more accute split use regular expression with the \w

preg_split('/[\s]+/',$string,1);

This would split words with boundaries to a limit of 1.

RobertPitt
  • 56,863
  • 21
  • 114
  • 161
2
$input = "Test me more";
echo preg_replace("/\s.*$/","",$input); // "Test"
markcial
  • 9,041
  • 4
  • 31
  • 41
2

strtok is quicker than extract or preg_* functions.

elitalon
  • 9,191
  • 10
  • 50
  • 86
HM2K
  • 1,461
  • 4
  • 16
  • 21
  • This answer seems more like a comment. It seems to be trying to weigh-in on other answers. I don't know how `extract()` is useful here. `preg_` functions will be slower, but they offer more robust techniques that can weed out unwanted characters in fringe cases. – mickmackusa Aug 11 '21 at 04:28
2

If you want to know how fast each of these respective functions is, I ran some crude benchmarking in PHP 7.3 on the six most voted answers here (strpos with substr, explode with current, strstr, explode with trim, str_word_count and strtok) with 1,000,000 iterations each to compare their speeds.

<?php

$strTest = 'This is a string to test fetching first word of a string methods.';

$before = microtime(true);
for ($i=0 ; $i<1000000 ; $i++) {
    $p = strpos($strTest, ' ');
    $p !== false ? $strTest : substr( $strTest, 0, $p );
}
$after = microtime(true);
echo 'strpos/ substr: '.($after-$before)/$i . ' seconds<br>';

$before = microtime(true);
for ($i=0 ; $i<1000000 ; $i++) {
    strstr($strTest, ' ', true);
}
$after = microtime(true);
echo 'strstr: '.($after-$before)/$i . ' seconds<br>';

$before = microtime(true);
for ($i=0 ; $i<1000000 ; $i++) {
    current(explode(' ',$strTest));
}
$after = microtime(true);
echo 'explode/ current: '.($after-$before)/$i . ' seconds<br>';

$before = microtime(true);
for ($i=0 ; $i<1000000 ; $i++) {
    $arr = explode(' ',trim($strTest));
    $arr[0];
}
$after = microtime(true);
echo 'explode/ trim: '.($after-$before)/$i . ' seconds<br>';

$before = microtime(true);
for ($i=0 ; $i<1000000 ; $i++) {
    str_word_count($strTest, 1);
}
$after = microtime(true);
echo 'str_word_count: '.($after-$before)/$i . ' seconds<br>';

$before = microtime(true);
for ($i=0 ; $i<1000000 ; $i++) {
    strtok($value, ' ');
}
$after = microtime(true);
echo 'strtok: '.($after-$before)/$i . ' seconds<br>';

?>

Here are the varying results from 2 consecutive runs:

strpos/ substr: 6.0736894607544E-8 seconds
strstr: 5.0434112548828E-8 seconds
explode/ current: 3.5163116455078E-7 seconds
explode/ trim: 3.8683795928955E-7 seconds
str_word_count: 4.6665270328522E-6 seconds
strtok: 4.9849510192871E-7 seconds

strpos/ substr: 5.7171106338501E-8 seconds
strstr: 4.7624826431274E-8 seconds
explode/ current: 3.3753299713135E-7 seconds
explode/ trim: 4.2293286323547E-7 seconds
str_word_count: 3.7025549411774E-6 seconds
strtok: 1.2249300479889E-6 seconds

And the results after inverting the order of the functions:

strtok: 4.2612719535828E-7 seconds
str_word_count: 4.1899878978729E-6 seconds
explode/ trim: 9.3175292015076E-7 seconds
explode/ current: 7.0811605453491E-7 seconds
strstr: 1.0137891769409E-7 seconds
strpos/ substr: 1.0082197189331E-7 seconds

Conclusion It turns out that the speed between these functions varies widely and is not as consistent between test runs as you might expect. According to these quick and dirty tests, any of the six chosen functions will get the job done in a reasonable amount of time. There are perturbations including other processes running that are interfering with the execution times. So just use whatever function makes the most practical and readable sense to you as a programmer. For the bigger programming picture, see Donald Knuth's Literate Programming.

Improv
  • 178
  • 1
  • 6
1

You question could be reformulated as "replace in the string the first space and everything following by nothing" . So this can be achieved with a simple regular expression:

$firstWord = preg_replace("/\s.*/", '', ltrim($myvalue));

I have added an optional call to ltrim() to be safe: this function remove spaces at the begin of string.

0

$first_word = str_word_count(1)[0]

Doesn't work on special characters, and will result in wrong behaviour if special characters are used. It is not UTF-8 friendly.

For more info check is PHP str_word_count() multibyte safe?

Dallas Caley
  • 5,367
  • 6
  • 40
  • 69
-2

If there is punctuation involved, then use preg_split()...

$string=" However, Lorem ipsum";
echo "[".preg_split('/[, ();.]/', trim($string))[0]."]";

See https://onlinephp.io/c/25087

user1432181
  • 918
  • 1
  • 9
  • 24
  • Why is comma nominated twice in the character class? Why use `trim()` when you can explicitly tell `preg_split()` to omit empty elements? If you only want the first element, then you should limit the number of splits so that the the function doesn't do unnecessary work. I would never use `preg_split()` for this task -- it is indirect programming to create an array from a string, then access the array to return a string. – mickmackusa Aug 29 '23 at 23:35