Remove a SINGLE instance of a substring from within a string (smart values)
Asked by Chris Smith:

Hi,

I am trying to remove a single instance of the string REM (which is a smart value) from the string TOT (which is also a smart value). Im within a branch when doing this but I dont think that the branch is the problem. So basically I want to do something like

Assign TOT.remove(REM) to TOT

If TOT is ABCDEFG and REM is CDE, then this works fine

But if TOT is ABCDEFGABCDEFG and REM is CDE, then I want it to only remove the first occurrence. But of course thats not the syntax of remove.

So I tried things like getting the left and right hand sides separately and then concatting

so left would be TOT.left(TOT.indexOf(REM))

and right would be TOT.right(TOT.indexOf(REM)+REM.length())

and so the whole thing would be

TOT.left(TOT.indexOf(REM)).concat(TOT.right(TOT.indexOf(REM)+REM.length()))

Except this means nesting smart values, and JIRA doesnt like that (at least thats what I understand).

So does anybody have a cunning way of doing this?


Answers:
author: Chris Smith
body: So I think I managed to get something working with doing result.concat(str.substringBefore(toBeReplaced).concat(str.substringAfter(toBeReplaced)

Anybody see a hole in the logic?

comments: author: Darryl Lee
body: Ah, yeah, that will work because **substringAfter** is matching the first occurrence of your string.

Nice one!


author: Darryl Lee
body: Hi [@Chris Smith](/t5/user/viewprofilepage/user-id/4935299)

As [@David Pezet](/t5/user/viewprofilepage/user-id/4480447) pointed out, this can be done with [replaceAll](https://support.atlassian.com/cloud-automation/docs/jira-smart-values-text-fields/#replaceAll-String-regex--String-replacement-) and the judicious use of [regular expressions](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html). So this worked for me:

```
{{TOT.replaceAll(REM.concat("(.+)"),"$1")}}
```

What it's doing is replacing REM and everything that comes after it, which is represented as (.+).

We are replacing that with the "captured" text (which is what the parentheses are for).

So then, in the string ABCDEFGABCDEFG we are replacing:

```
CDE(FGABCDEFG)
```

with

```
FGABCDEFG
```

Hopefully that's clear.

P.S. [@David Pezet](/t5/user/viewprofilepage/user-id/4480447) I am very interested in what undocumented Java functions you've found. **removeFirst** did not work for me.

comments: author: David Pezet
body: [@Darryl Lee](/t5/user/viewprofilepage/user-id/1365322) Unfortunately I don't immediately recall, and don't have a list. This was a while back. The page seems a lot more complete than I remember, so it is possible it is now up to date (or I could be mis-remembering). If I happen across any, I'll try to remember to update here.


author: Chris Smith
body: Hi Darryl, Thanks for the tip - so is this regex just replacing the first occurrence (which is what I wanted), or all occurrences?


author: Darryl Lee
body: Oof, was going through my old answers, and realized I didn't reply [@Chris Smith](/t5/user/viewprofilepage/user-id/4935299) , sorry - yes, this replaces only the first occurrence of REM.

Even though the function is called **replaceAll**, what we are replacing is CDE+"everything that follows it" (that's what the "(.+)" is about) with just everything that follows it (that's what the "$1" is about).

There's only one instance of CDE+"everything that follows it", so in effect it's only doing one replacement.

Regex is weird. I know. I tested this here: <https://regex101.com/>

It's a super-useful site:

![Screen Shot 2023-03-25 at 11.24.26 PM.png](https://community.atlassian.com/t5/image/serverpage/image-id/247769i817A15249A38A2DB/image-size/large?v=v2&px=999 "Screen Shot 2023-03-25 at 11.24.26 PM.png")


author: David Pezet
body: You can try using String[.replacefirst()](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceFirst(java.lang.String,%20java.lang.String)) (I have not tried this myself) or you can try a regular expression that accomplishes what you are looking with String[.replaceAll()](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceAll(java.lang.String,%20java.lang.String)) (which I have used). There are lots of online tools to help figure out the regex (e.g., regex101). Hope this helps.

comments: author: Chris Smith
body: Hi David - thanks for the reply. I dont see a replaceFirst in the JIRA reference? <https://support.atlassian.com/cloud-automation/docs/jira-smart-values-text-fields/>


author: David Pezet
body: Right. I've had some luck using other Java functions that aren't expressly listed, so worth a shot to try if it makes it any easier for you. Otherwise, you may need to figure out a regular expression that only returns the first instance maybe through greedy/ungreedy options or groupings.