1

I need help a with building a regex for extracting a particular string and manipulating it. Here's the example

Actual Input:

( 12s ) Agent K: Hello Guest, How are you doing today?<br> <br>How Can I help<br>
( 18s ) Guest:   Hello there! Need access to XYZ<br>
( 53s ) Agent K: Granted the access<br>
( 1m 9s ) Guest: Ok thanks, Agent K<br>

I want to identify the appearances of "Agent K:", "Guest:" and all timings coming within brackets and manipulate it to

<b>Agent K:</b>.12s Hello Guest, How are you doing today?<br> <br>How Can I help<br>
<b>Guest:</b>.18s   Hello there! Need access to XYZ<br>
<b>Agent K:</b>.53s Granted the access<br>
<b>Guest:</b>.1m 9s Ok thanks, Agent K<br>

I started writing regex function to identify the appearances of ) Agent K: and ) Guest: so that I'm uniquely identifying their places. For that, I'm using below which returns true

string htmlValue = '<br>( 15s ) Agent K: Test Message from user';

string s1 = ') Agent K:';

Boolean found = Pattern.compile('(?i)' + Pattern.quote(s1)).matcher(htmlValue).find();

But I'm not sure how I can move next to start manipulating it. Any help is greatly appreciated!

1 Answer 1

2

You can use String.replaceAll to do this in one tidy step:

String output = input.replaceAll(
  '(?m)^\\s*\\(\\s*(.+?)\\s*\\)\\s*(.+?:)\\s*\\s*(.+)\\s*$',
  '<strong>$2</strong>.$1 $3'
);

Here's an example output:

String input = '( 12s ) Agent K: Hello Guest, How are you doing today?<br> <br>How Can I help<br>\n( 18s ) Guest:   Hello there! Need access to XYZ<br>\n( 53s ) Agent K: Granted the access<br>\n( 1m 9s ) Guest: Ok thanks, Agent K<br>';
String output = input.replaceAll(
  '(?m)^\\s*\\(\\s*(.+?)\\s*\\)\\s*(.+?:)\\s*\\s*(.+)\\s*$',
  '<strong>$2</strong>.$1 $3'
);
System.debug(output);

Result:

<strong>Agent K:</strong>.12s Hello Guest, How are you doing today?<br> <br>How Can I help<br>
<strong>Guest:</strong>.18s Hello there! Need access to XYZ<br>
<strong>Agent K:</strong>.53s Granted the access<br>
<strong>Guest:</strong>.1m 9s Ok thanks, Agent K<br>

There's a ton of regex here, but it's simple. I'll break it down:

  • ( and ) create "numbered capture groups"
  • (?m) multiline mode, matches newlines with ^ and $
  • ^ Start of a line (in beginning position)
  • $ End of a line (in end position)
  • \\s* Zero or more spaces (we use this a lot to skip whitespace)
  • \\( and \\), literal parentheses
  • (.+?) Match any character sequence, but non-greedy (so, up to the next )).
  • (.+?:) match any sequence ending in :.
  • (.+) match to end of line

And for the replacement string, $1 refers to the first capture group, $2 to the second group, etc.

P.S. <b> and <i> are strongly discouraged in modern HTML. You should use <strong> for bold emphasis (a keyword or heavy emphasis, a concept that must be understood), and <i> should now be <em> for emphasis.

9
  • Possibly worth noting that <strong> should be preferred over <b> in most cases.
    – Adrian Larson
    Commented May 13, 2021 at 18:19
  • @AdrianLarson Fair, semantics are important in HTML, this was more a focus on the technique.
    – sfdcfox
    Commented May 13, 2021 at 18:20
  • Absolutely, I figured as much.
    – Adrian Larson
    Commented May 13, 2021 at 18:21
  • @sfdcfox This is extremely helpful.. Thank you so much for this and especially breaking it down with explanation. It works like a charm! Commented May 14, 2021 at 8:58
  • @sfdcfox I have one small issue with it. My each message doesn't end with \n and it ends something like this in actual ( 12s ) Agent K: Test msg <br>( 14s ) Guest: Reply msg <br> some on next line <br>( 18s ) Agent K: New msg Hence I believe the last group (.+) that is looking until end of line need a change. Could you please suggest for that too? I tried few things but doesn't work well Commented May 14, 2021 at 10:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .