Regex Issue

Hello All,

I have a string that can theoritically have “N” forward slashes in it. I want to remove only the last one.

Var strInput, strOutput As String
Var re as New RegEx

strInput = "Some text that I need for this example / And yet some more text I need /"
re.SearchPattern = "/$"
re.ReplacementPattern = ""
re.SearchStartPosition = strInput.Length - 3
strOutput = re.Replace(strInput)

In the output I see both the slashes still in the string.
Any idea where I am going awry?

is the last / always at the end of the line ?

Give or take a space or two, yes.
I know I could just as easily do:

strOutput = strInput.Left(strInput.length-2)

And that would get it “most” of the time, but not all the time.

You need to loop through to find the start position after the last successful match, and subtract 1

Var re As New RegEx
Var match As RegExMatch
Var mystring As String = "Some text that I need for this example / And yet some more text I need /. test"

re.SearchPattern = "/"

Var lastposition As Integer = -1

Var result As String

match = re.Search(mystring)
Do
  
  If match <> Nil Then
    
    result = match.SubExpressionString(0)
    lastposition = re.SearchStartPosition - 1
  End If
  
  match = re.Search
Loop Until match Is Nil


If lastposition <> -1 Then
  
  re.SearchPattern = "/"
  re.ReplacementPattern = ""
  re.Options.ReplaceAllMatches = True
  
  mystring = re.Replace(mystring, lastposition)
  
  MessageBox(myText)
End If

then try TrimRight(" /") (with a space and a /)

Thanks @Mark_Sweeney and @Jean-Yves_Pochez ! I will give that a go and let you guys know if I have any issues. :slight_smile:

Assuming that I understand correctly and you want to remove the last slash and everything after it, here’s a quickly produced function:

Public Function dropLastSegment(value as String, separator as String) As String
  var segments() as String = value.ToArray( separator )
  call segments.Pop
  Return String.FromArray( segments, separator )
End Function

Usage:

var input as String = "a/b/c/d/e/f/g/h"
var result as String = dropLastSegment( input, "/" )

Result:

a/b/c/d/e/f/g
1 Like

Thanks @Anthony_G_Cyphers

1 Like

The pattern you want is:

(.+)\/(.+?)

Use it like this:

dim r as RegEx

r=new RegEx

r.SearchPattern="(.+)\/(.+?)"
r.ReplacementPattern="\1\2"

dim start as string = "a/b/c/d/e/f/g"

dim result as string

result=r.Replace(start)

I’m not sure if this is faster than Anthony’s excellent use of the To/FromArray functions, but it might be. One way to speed up ReEx is to cache the RegEx object – you can use it over and over again once you’e created it and set the search and replace patterns.

Why wouldn’t the Replacement pattern be just “\1”?

He only wants to remove the last slash, preserving any text after it.

My apologies for any lack of clarity on my part. There is nothing past the last forward slash except maybe some white space.

So you can trim space right and then trim / right, correct?

Yes, that works well.

What confused me is this,

As an example we have been provided (by someone other than the OP)

a/b/c/d/e/f/g/h

and we are told the goal is

a/b/c/d/e/f/g

The last forward slash and everything after is removed.

However, when I try this in BBEdit where I do my Regex testing

“(.+)/(.+?)” [SearchPattern]

a/b/c/d/e/f/g/h → a/b/c/d/e/f/gh [ReplacementPattern is “\1\2”]
a/b/c/d/e/f/g/h → a/b/c/d/e/f/g [ReplacementPattern is “\1”]

I thought the second was the goal and therefore the second ReplacementPattern would be used.

Indeed. I misread the post.