0

How can I get the next word after pregmatch with PHP.

For example, If I have a string like this:

"This is a string, keyword next, some more text. keyword next-word."

I want to use a preg_match to get the next word after “keyword”, including if the word is hyphenated.

So in the case above, I want to return “next” and ”next-word”

I’ve tried :

$string = "This is a string, keyword next, some more text. keyword next-word.";

$keywords = preg_split("/(?<=\keyword\s)(\w+)/", $string);
print_r($keywords);

Which just returns everything and doesn’t seem to work at all.

Any help is much appreciated.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
user3143218
  • 1,738
  • 5
  • 32
  • 48
  • `strpos` gives you where something shows up and makes it easy to find the point afterwards. –  Jun 15 '14 at 03:51
  • strpos only returns the first occurrence though. I want to push everything to an array – user3143218 Jun 15 '14 at 03:55
  • Ah, fair enough. My regex experience doesn't know the `<=` part of the regex you provided, though. Sorry. –  Jun 15 '14 at 03:58
  • 1
    @JeremyMiller FWIW, that `(?<=` is part of a positive lookbehind. So if someone were using `(?<=a)b` that would mean `b` is only matched if preceded by `a`. More info here: http://www.regular-expressions.info/lookaround.html – Giacomo1968 Jun 15 '14 at 04:10

3 Answers3

8

Using your example this should work using preg_match_all:

// Set the test string.
$string = "This is a string, keyword next, some more text. keyword next-word. keyword another_word. Okay, keyword do-rae-mi-fa_so_la.";

// Set the regex.
$regex = '/(?<=\bkeyword\s)(?:[\w-]+)/is';

// Run the regex with preg_match_all.
preg_match_all($regex, $string, $matches);

// Dump the resulst for testing.
echo '<pre>';
print_r($matches);
echo '</pre>';

And the results I get are:

Array
(
    [0] => Array
        (
            [0] => next
            [1] => next-word
            [2] => another_word
            [3] => do-rae-mi-fa_so_la
        )

)
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
  • 1
    Wow that's super nice! Thanks so much for your help :) – user3143218 Jun 15 '14 at 04:21
  • @user3143218 Thanks! And I just made it nicer! – Giacomo1968 Jun 15 '14 at 04:24
  • 1
    You can remove `_` from the character class, the non capturing group and the s modifier. – Casimir et Hippolyte Jun 15 '14 at 04:25
  • @CasimiretHippolyte I added `_` on purpose to show how differ not alphabet characters can be used. But just tried it without `_` and that works? Why? If I remove `-` the test fails with only a cut in half word? – Giacomo1968 Jun 15 '14 at 04:28
  • 1
    Nice, I did it as preg_match instead of preg_match_all and used echo $matches{0] to show the first word after $regex = '/(?<=\b'.$var.'\s)(?:[\w-]+)/is'; -- Needed this script. Ty for the code – Michael d Apr 19 '17 at 05:45
0

Positive look behind is what you are looking for:

(?<=\bkeyword\s)([a-zA-Z-]+)

Should work perfect with preg_match. Use g modifier to catch all matches.

Demo

Reference Question: How to match the first word after an expression with regex?

Community
  • 1
  • 1
Shark
  • 257
  • 2
  • 13
  • “Use `g` modifier to catch all matches.” You mean the `i` modifier for case-`i`nsensitive, right? – Giacomo1968 Jun 15 '14 at 04:16
  • Then why not use `/(?<=\bkeyword\s)([A-Z-]+)/is`? Or `/(?<=\bkeyword\s)(?:[A-Z-]+)/is` so as to not duplicate returned results from a capture group? Also, `g` is a JavaScript modifier. Won’t work in PHP. – Giacomo1968 Jun 15 '14 at 04:25
  • @JakeGould 1 : `/(?<=\bkeyword\s)([A-Z-]+)/` will only catch capital letters, 2: `is` will only catch first match, 3: `g` works in pcre php and catches all matches found in a string. [Demo](http://regex101.com/r/jQ3bV9) of your regex proves that. And while you take a look at the demo, plz notice on left side under the flavour heading, this demo is for pcre php. – Shark Jun 15 '14 at 04:33
  • @JakeGould Still I upvoted your answer because its in more detail. And serves the cause for the asker. :) – Shark Jun 15 '14 at 04:35
  • 1
    Thanks for the correction. Please stop taking constructive criticism—which might be wrong but is being asked in good faith—so personally & react so “dude”. Okay? – Giacomo1968 Jun 15 '14 at 04:37
  • @JakeGould Understood. I removed the part of my comment that you didnt like. – Shark Jun 15 '14 at 04:39
0

While regex is powerful, it's also for most of us hard to debug and memorize.

On this particular case, Get next word after ... match with PHP, which is a very common string operation.

Simply, by exploding the string in an array, and searching the index. This is useful because we can specify how much words forward or backward.

This match the first occurrence + 1 word:

<?php
$string = explode(" ","This is a string, keyword next, some more text. keyword next-word.");
echo $string[array_search("keyword",$string) + 1];
/* OUTPUT next, *

Run it online

By reversing the array, we can catch the last occurrence - 1 word:

<?php
$string = array_reverse(explode(" ","This is a string, keyword next, some more text. keyword next-word."));
echo $string[array_search("keyword",$string) - 1];
/* OUTPUT next-word. */

Run it online

This is good for performances if we are making multiples searches, but of course the length of the string must be kept short (whole string in memory).

NVRM
  • 11,480
  • 1
  • 88
  • 87