Replace this regexp '/imgur.com\/(?!memegen\/create)/'
with this one:
'/(?<!\[wpws\surl="http:\/\/)imgur.com\/(?!memegen\/create)/'
The shortcode still gets converted to
[wpws url="http://i.imgur.com/memegen/create/a/zaNdd/all" query=".posts"]
This is what the code looks like after your proposed edit:
add_filter('wp_insert_post_data', 'pm_add_memegen');
function pm_add_memegen( $data ) {
$data['post_content'] = preg_replace('/(?<!\[wpws\surl="http:\/\/)imgur.com\/(?!memegen\/create)/', 'imgur.com/memegen/create/', $data['post_content']);
return $data;
}
Thanks for the suggestion though 🙂
http://i.imgur
Where did the i sub-domain come from? Is that part of the original URL? If so, any idea what the possible range of sub-domains might be – as in longest possible characters in the sub-domain. I think sub-domains could be accommodated in the regexp with a slight adjustment.
I’m fairly sure shortcodes without imgur subdomains do not get converted, am I right?
What the i does I’m not entirely sure. You can remove or add it to any of their addresses and every page still loads like they would otherwise.
eg:
http://imgur.com/a/s9CIv/all
http://i.imgur.com/a/s9CIv/all
http://i.imgur.com/yNf67Rt.png
http://imgur.com/yNf67Rt.png
Both instances get converted.
[wpws url=”http://i.imgur.com/a/zaNdd/all” query=”.posts”]
Becomes
[wpws url=”http://i.imgur.com/memegen/create/a/zaNdd/all” query=”.posts”]
[wpws url=”http://imgur.com/a/zaNdd/all” query=”.posts”]
Becomes
[wpws url=”http://imgur.com/memegen/create/a/zaNdd/all” query=”.posts”]
Hmmm, that’s disappointing. The regexp worked correctly on my installation. I wonder if it has to do with how you implemented my original code by using a plugin. You misunderstood where to place my code in our previous thread, I meant your theme’s functions.php, not wp-includes/functions.php.
Since the plugin approach was working for you I let it go, but now I wonder if the plugin is not accepting the negative look behind code that should have prevented changes to shortcode URLs. Try placing the code on your theme’s functions.php and deactivating the code plugin. Be advised that when you alter a theme’s code, the changes could be lost when the theme updates. A couple ways around this is to create a child theme or a simple plugin to contain the code.
I have no idea what’s going wrong on my end.
I removed the code from the plugin and added the code to my themes functions.php and the shortcode still gets converted.
It could be differences in PHP versions or installed modules. I’ve been led to believe the negative look behind syntax I used is not universally supported. So it’s not that there’s anything wrong on your end, it’s just different. That leaves us with how to exclude shortcodes without negative look behind.
I don’t see a way with a single regexp. One possible approach would be to use other PHP string functions to break up the post content into shortcode and non-shortcode pieces and only apply the preg_replace to the non-shortcode pieces. Then reassemble the pieces back together again.
A couple passes with explode() should do it, first on ‘[wpws’, then on ‘]’. However, dealing with edge conditions where the shortcode is the very first or very last element complicates things, as well as the possible occurrence of ‘]’ that is not related to a shortcode. I’m not able to offer functional code for this, but at least you know there is a way to deal with this issue. It’s not hopeless.
Very insightful. Thanks again for your detailed help.
I just learned something new to me last night that could be useful in your situation. I suggested 2 passes because I didn’t think there was a way to capture the delimiter if it were the entire shortcode. As it turns out there is a way with preg_split() by using the PREG_SPLIT_DELIM_CAPTURE flag.
http://php.net/manual/en/function.preg-split.php
By splitting the content with preg_split('/(\[wpws.*?])/', $content, -1, PREG_SPLIT_DELIM_CAPTURE ), you should get an array of alternating content segments and shortcodes. By only applying our initial preg_replace() to segments that do not start with ‘[wpws’, then once the segments are re-assembled into a single content value, you should have the results you seek.