regex guru required

Nov 09, 2017 15 Replies

Given the string:



Word_1Word_3Word_4



What regex magicary for PHP's preg_match_all that can extract just the text of the "Word_n" fields *including* the empty Word_2. That is I want a list or four variables filled with Word_1, Word_2, Word_3 and Word_4 even when a field is empty. The "words" change and so does the color. The actual string is longer but all subsequent fields follow the same format as Word_3.



Just dumping everything between < and > or collecting everything between > and < doesn't work as there are effectively empty matches between adjacent tags. So you end up with



$1 = "" $2 = "Word_1" $3 = "" $4 = "" $5 = "" $6 = "" (This would be "Word_2" if it wasn't empty) $7 = "" $8 = "Word_3" $9 = "" $10 = "Word_4"



Rather than:



$1 = "Word_1" $2 = "" (This would be "Word_2" if it wasn't empty) $3 = "Word_3" $4 = "Word_4"



Reliably finding the end of each word is easy with: (.*?)


No immediate answer, but I find using the online "regex tinkering tools" helps, e.g.

formatting link

yes, that seems to work in the general case, so the regex you want is

]*>(?:]*>)?([^>]*)(?:)?

Whats left, if anything, will be the wanted words

If you want it more general, so it will capture the inner text from within either a single, or double nested set of html elements, regardless of what the element types are ...

I once had to do a similar task, and regex really isn't the right answer. Better to use a program that just strips out what isn't wanted.

(there was a guy, maybe this group, can't remember, who had about 400 web pages on WWI bombing missions and he just wanted to extract names of crew; the pages had been written by different people and weren't consistent)

If I had a choice something that could read the html document and access it through the DOM model, perhaps with XPath, and PHP is almost never my weapon of choice ...

I used this:

formatting link

A program over 50 years old....!

Trouble is if there is nothing left (empty field) it doesn't return anything for that position.

PHP will return a null string.

And for that, I've used CSS selectors with Pup.

formatting link

Which works a bit like jq on json.

return

It didn't they ways I tried.

And Andy yes, I did see your posts and solution that does work, thank you. Now need to a) work out what it's doing, I think it's the ?:(...)? construct. b) investigate the site you used.

As for PHP not being the best tool, maybe, but it's part of an existing PHP page that works apart from that one little niggle.

that's the thing with regex ... don't ask me in 6 months what it's doing, especially the 3rd version!

Rather than using .* to match the remainder of html tags I used [^>]* which is less greedy, to match everything up to, but not including the closing chevron to make sure it matches just a single tag at a time.

That's a non-capturing group since you're not really interested in the second level of html tags wrapping the inner text, other than to notice and skip them, that way you don't need to worry about the "Nth" match varying depending if the span tags exist or not,

so it matches ...

CAPTURED-TEXT

of course it could get confused if the site you're scraping from suddenly uses a third level of tags inside the span for some rows.

b) investigate the site you used.

I've found it handy several times.

I have been trying to avoid picking sides between Go and Rust ...

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required