2
votes

So i'm trying to create a Regex find and replace function to take the Source Medium Path dimension from Google Analytics, and return a value that matches up with the Source Medium dimension. For example, when I'm looking at the total conversions for Source Medium Path, I get values like:

  1. google / cpc > google / organic
  2. google / cpc > google / organic > (direct) / (none)
  3. google / organic
  4. (none) > (none) > (none) > google / organic > (direct) / (none) > (direct) / (none)
  5. (direct) / (none)

This isn't the prettiest format and will be difficult for our clients to understand in their reporting, so I'd like to replace these values with their equivalent Source / Medium dimension:

  1. google / organic
  2. google / organic
  3. google / organic
  4. google / organic
  5. (direct) / (none)

The Regex find/replace function I've tried so far looks like it works for everything except the #4, where the Path ends with multiple iterations of 'direct / (none)', and mistakenly pulls in '(direct) / (none)' instead of 'google / organic'.

Essentially, this should find the last Source / Medium in the Path (ie 'google / organic' in 1 and 3), unless the last Group is '(direct) / (none)' (like in 2/4/5), in which case it should use the last Group that isn't '(direct) / (none)', and replace with the Source / Medium, unless the Path only contains one or more iterations of '(direct) / (none)', in which case it should replace with the value '(direct) / (none).

Any help in how I can fix this would be much appreciated! See below for what I have so far:

find: ^(.* \/ .* > )*(?'foo'.* \/ .*) > (direct \/ \(none\))+$|^(.* \/ .* > )(?'var'.* \/ .*)$

replace with: ${foo}${var}

1
Try ^(?:(?:\(none\) > )+|(?:\w+ \/ \w+ > ))?(\w+ \/ \w+)(?!\S).* and replace with group 1 See regex101.com/r/L6MnWN/1 - The fourth bird
Thank you! that definitely fixed the issue I described. However, I realized I forgot an important piece, being that if the Path only contains one or more iterations of '(direct) / (none)' then it should replace that value with just '(direct) / (none)'. For example: (direct) / (none) > (direct) / (none) > (direct) / (none) and (direct) / (none) should both be replaced with '(direct) / (none)'. I'm trying to figure out how to make that work with what you provided, but any help would be much appreciated! - aceetobee
Like this? ^(?:(?:\(none\) > )+|(?:\w+ \/ \w+ > ))?(\w+ \/ \w+|\(direct\) \/ \(none\))(?!\S).* regex101.com/r/NQrhXr/1 - The fourth bird

1 Answers

2
votes

You might use a pattern to optionally match the preceding parts with none or word chars followed by a / and >

Then use a capturing group for either a (none) > (none) part or word / word part and use that in the replacement.

After group 1 you can match the rest of the string so that it will not be present in the replacement.

^(?:(?:\(none\) > )+|(?:\w+ \/ \w+ > ))?(\w+ \/ \w+|\(direct\) \/ \(none\))(?!\S).*

Regex demo

In the replacement use group 1 $1