Find and Replace with ASP Classic - regex

I have an function in ASP VB. and I need to replace the exact word in it. For example I have an string like "wool|silk/wool|silk". I want to replace just silk and not silk/wool.
' "|" is a devider
cur_val = "wool|silk/wool|silk"
cur_val_spl = Split("wool|silk/wool|silk", "|")
key_val = "silk"
For Each i In cur_val_spl
If i = key_val Then
cur_val = Replace(cur_val, ("|" & i), "")
cur_val = Replace(cur_val, i, "")
End If
Next
Response.Write(cur_val)
In this case my result would be "wool/wool" but what I really want is this "wool|silk/wool".
I really appreciate any help.

You should build a new string as you go
' "|" is a devider
cur_val = "wool|silk/wool|silk"
cur_val_spl = Split("wool|silk/wool|silk", "|")
result = ""
key_val = "silk"
addPipe = false
For Each i In cur_val_spl
If i <> key_val Then
if addPipe then
result = result & "|"
else
addPipe = true
end if
result = result & i
End If
Next
Response.Write(result)

you could do it with a regular expression but this is shorter
cur_val = "wool|silk/wool|silk"
Response.Write left(mid(replace("|"&cur_val&"|","|wool|","|silk|"),2),len(cur_val))
'=>silk|silk/wool|silk
Too bad you allready accepted the other answer 8>)

Related

Select text strings with multiple formatting tags within

Context:
VB.NET application using htmlagility pack to handle html document.
Issue:
In a html document, I'd like to prefixe all the strings starting with # and ending with space by an url whatever formatting tags are used within.
So #sth would became http://www.anything.tld/sth
For instance:
Before:
<p>#string1</p> blablabla
<p><strong>#stri</strong>ng2</p> bliblibli
After:
<p>#string1 blablabla</p>
<p><strong>#stri</strong>ng2 bliblibli</p>
I guess i can achieve this with html agility pack but how to select the entire text string without its formatting ?
Or should i use a simple regex replace routine?
Here's my solution. I'm sure it would make some experienced developpers bleed from every hole but it actually works.
The htmlcode is in strCorpusHtmlContent
Dim matchsHashtag As MatchCollection
Dim matchHashtag As Match
Dim captureHashtag As Capture
Dim strHashtagFormatted As String
Dim strRegexPatternHashtag As String = "#([\s]*)(\w*)"
matchsHashtag = Regex.Matches(strCorpusHtmlContent, strRegexPatternHashtag)
For Each matchHashtag In matchsHashtag
For Each captureHashtag In matchHashtag.Captures
Dim strHashtagToFormat As String
Dim strHashtagValueToFormat As String
' Test if the hashtag is followed by a tag
If Mid(strCorpusHtmlContent, captureHashtag.Index + captureHashtag.Length + 1, 1) = "<" Then
strHashtagValueToFormat = captureHashtag.Value
Dim intStartPosition As Integer = captureHashtag.Index + captureHashtag.Length + 1
Dim intSpaceCharPostion As Integer = intStartPosition
Dim nextChar As Char
Dim blnInATag As Boolean = True
Do Until (nextChar = " " Or nextChar = vbCr Or nextChar = vbLf Or nextChar = vbCrLf) And blnInATag = False
nextChar = CChar(Mid(strCorpusHtmlContent, intSpaceCharPostion + 1, 1))
If nextChar = "<" Then
blnInATag = True
ElseIf nextChar = ">" Then
blnInATag = False
End If
If blnInATag = False And nextChar <> ">" And nextChar <> " " Then
strHashtagValueToFormat &= nextChar
End If
intSpaceCharPostion += 1
Loop
strHashtagToFormat = Mid(strCorpusHtmlContent, captureHashtag.Index + 1, intSpaceCharPostion - captureHashtag.Length)
Else
strHashtagToFormat = captureHashtag.Value
End If
strHashtagFormatted = "" & strHashtagToFormat & ""
strCorpusHtmlContent = Regex.Replace(strCorpusHtmlContent, strHashtagToFormat, strHashtagFormatted)
Next
Next
Before:
<p>#has<strong>hta</strong><em>g_m</em>u<span style="text-decoration: underline;">ltifortmat</span> to convert</p>
After:
<p>#has<strong>hta</strong><em>g_m</em>u<span style="text-decoration: underline;">ltiformat</span> to convert</p>

How can I split an array in VBA with a delimiter based on a regex condition?

I have an input like:
apple, orange, (pear, banana, grape), mango
that I want to split as:
apple
orange
(pear, banana, grape)
mango
I don't understand the regex fully, but I think I would use ,(?![^()]*)) which I found here - Java split string on comma(,) except when between parenthesis ()
I am using VBA, so if I have the input stored in an array, I would typically do:
array = Split(string, ",")
But this would yield the result as:
apple
orange
(pear
banana
grape)
mango
which I don't want.
I'm pretty sure I can find a way to replace ( and ) with nothing so they disappear from the output, but I don't know how to feed my regex string logic to my VBA formula.
I thought something like this would work:
array = Split(string, ",(?![^()]*\))")
But it doesn't. I did enable the "Microsoft VBScript Regular Expressions 5.5" reference but it didn't seem to help.
Any advice is appreciated.
Thank you,
Alternative to RegEx:
Sub mytry()
Dim str As String
str = "apple, orange, (pear, banana, grape), mango "
Dim perenSplt() As String
perenSplt = Split(Replace(str, ")", ")("), "(")
str = ""
Dim i As Long
For i = LBound(perenSplt) To UBound(perenSplt)
If InStr(perenSplt(i), ")") Then
perenSplt(i) = "(" & Replace(perenSplt(i), ",", "|")
End If
str = str & perenSplt(i)
Next i
Dim finalSplt() As String
finalSplt = Split(str, ",")
For i = LBound(finalSplt) To UBound(finalSplt)
If InStr(str, "(") > 0 Then
finalSplt(i) = Trim(Replace(finalSplt(i), "|", ","))
Else
finalSplt(i) = Trim(finalSplt(i))
End If
Next i
ActiveSheet.Range("A1").Resize(,UBound(finalSplt) + 1) = finalSplt
End Sub
another possibility out of RegEx:
Function GetArray(ByVal str As String) As Variant
Dim s As String, v As Variant
For Each v In Split(Replace(str & " ", ")", "("), "(")
s = s & IIf(Right(v, 1) <> " ", "(" & v & ")", Replace(v, ",", "|"))
Next
GetArray = Split(Replace(WorksheetFunction.Trim(s), "| ", "|"), "|")
End Function
which you can use in your main code like:
Dim myArray As Variant
myArray = GetArray("apple, orange, (pear, banana, grape), mango")
Range("A1").Resize(ubound(myArray) + 1).Value = Application.Transpose(myArray)

Tokenise mathematical (infix) expression in VBA

I need to tokenize a mathematical expression using VBA. I have a working solution but am looking for a more efficient way of doing it (possibly RegExp).
My current solution:
Function TokeniseTheString(str As String) As String()
Dim Operators() As String
' Array of Operators:
Operators = Split("+,-,/,*,^,<=,>=,<,>,=", ",")
' add special characters around all "(", ")" and ","
str = Replace(str, "(", Chr(1) & "(" & Chr(1))
str = Replace(str, ")", Chr(1) & ")" & Chr(1))
str = Replace(str, ",", Chr(1) & "," & Chr(1))
Dim i As Long
' add special characters around all operators
For i = LBound(Operators) To UBound(Operators)
str = Replace(str, Operators(i), Chr(1) & Operators(i) & Chr(1))
Next i
' for <= and >=, there will now be two special characters between them instead of being one token
' to change < = back to <=, for example
For i = LBound(Operators) To UBound(Operators)
If Len(Operators(i)) = 2 Then
str = Replace(str, Left(Operators(i), 1) & Chr(1) & Chr(1) & Right(Operators(i), 1), Operators(i))
End If
Next i
' if there was a "(", ")", "," or operator next to each other, there will be two special characters next to each other
Do While InStr(str, Chr(1) & Chr(1)) > 0
str = Replace(str, Chr(1) & Chr(1), Chr(1))
Loop
' Remove special character at the end of the string:
If Right(str, 1) = Chr(1) Then str = Left(str, Len(str) - 1)
TokeniseTheString = Split(str, Chr(1))
End Function
Test using this string IF(TestValue>=0,TestValue,-TestValue) gives me the desired solution.
Sub test()
Dim TokenArray() As String
TokenArray = TokeniseTheString("IF(TestValue>=0,TestValue,-TestValue)")
End Sub
I have never seen regular expressions before and tried to implement this into VBA. The problem I am having is that the RegExp object in VBA doesn't allow positive lookbehind.
I will appreciate any more efficient solution than mine above.
As suggested by #Florent B, the following function gives the same results using RegExp:
Function TokenRegex(str As String) As String()
Dim objRegEx As New RegExp
Dim strPattern As String
strPattern = "(""(?:""""|[^""])*""|[^\s()+\-\/*^<>=,]+|<=|>=|\S)\s*"
With objRegEx
.Global = True
.MultiLine = False
.IgnoreCase = True
.Pattern = strPattern
End With
str = objRegEx.Replace(str, "$1" & ChrW(-1))
If Right(str, 1) = ChrW(-1) Then str = Left(str, Len(str) - 1)
TokenRegex = Split(str, ChrW(-1))
End Function

Regex for strings not starting with "My" or "By"

I need Regex which matches when my string does not start with "MY" and "BY".
I have tried something like:
r = /^my&&^by/
but it doesn't work for me
eg
mycountry = false ; byyou = false ; xyz = true ;
You could test if the string does not start with by or my, case insensitive.
var r = /^(?!by|my)/i;
console.log(r.test('My try'));
console.log(r.test('Banana'));
without !
var r = /^([^bm][^y]|[bm][^y]|[^bm][y])/i;
console.log(r.test('My try'));
console.log(r.test('Banana'));
console.log(r.test('xyz'));
if you are only concerned with only specific text at the start of the string than you can use latest js string method .startsWith
let str = "mylove";
if(str.startsWith('my') || str.startsWith('by')) {
// handle this case
}
Try This(Regex is NOT case sensitive):
var r = /^([^bm][y])/i; //remove 'i' for case sensitive("by" or "my")
console.log('mycountry = '+r.test('mycountry'));
console.log('byyou= '+r.test('byyou'));
console.log('xyz= '+r.test('xyz'));
console.log('Mycountry = '+r.test('Mycountry '));
console.log('Byyou= '+r.test('Byyou'));
console.log('MYcountry = '+r.test('MYcountry '));
console.log('BYyou= '+r.test('BYyou'));

`Nothing` in macro crashes Excel 2013

I'm trying to use RegEx in an Excel 2015 macro. I don't know if I'm doing something wrong, but every time I run it, my Excel crashes. Here's the macro:
Sub MakeExplicit()
Dim whitespace As RegExp
Set whitespace = New RegExp
whitespace.Pattern = "\s+"
whitespace.MultiLine = True
whitespace.Global = True
Dim implicit As RegExp
Set implicit = New RegExp
implicit.Pattern = "^\d+-\d+$"
Dim row As range
For Each row In ActiveSheet.UsedRange.Rows
Dim first As range
Set first = row.Cells(1, 1)
Dim str As String
str = first.Text
str = whitespace.Replace(str, Nothing)
If implicit.Test(str) Then 'FIXME here it crashes
Dim FromTo As Variant
FromTo = Split(str, "-")
Dim sFrom, sTo As Integer
sFrom = FromTo(1)
sTo = FromTo(2)
' doplň chybějící číslice
' např [2345, 78] doplní
' na [2345, 2378]
sTo = Left( _
sFrom, _
Len(sFrom) - Len(sTo) _
) + sTo
Dim iFrom, iTo As Integer
iFrom = CInt(sFrom)
iTo = CInt(sTo)
If iFrom > iTo Then _
Err.Raise 42, first.Address, _
"Wrong order of numbers!"
Dim i As Integer
For i = iFrom To iTo
' some more code
Next i
End If
Next row
End Sub
By using the Debugger I found out it crashes when the code reaches "If implicit.Test(str) Then" implying there's something wrong with RegEx. These are the project's references:
The obvious question is how do I get it to work? VBA is a very ugly language by itself, so I have no preference about how, just making it work is enough.
this is the line that crashes
str = whitespace.Replace(str, Nothing)
Nothing is used for destroying objects ... set object = nothing
use instead
str = whitespace.Replace(str, "")
or, as per Mat's Mug
str = whitespace.Replace(str, vbNullString) ' uses less memory and is more readable
A few things...
1) The line If implicit.Test(str) Then should not cause an error.
2) To replace one or more spaces with no spaces, use "" instead of Nothing...
str = whitespace.Replace(str, "")
3) Since the Split function returns a 0-based array, use...
sFrom = FromTo(0)
sTo = FromTo(1)
4) To concatenate, use the ampersand (&) instead of the plus sign (+)...
sTo = Left( _
sFrom, _
Len(sFrom) - Len(sTo) _
) & sTo
Hope this helps!