I'm looking for an ASP equivalent to strtr PHP function.
I use it to encrypt in ROT47
This is my PHP code:
function rot47_encrypt($str)
{
return strtr($str,
'!"#$%&\'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNO'
);
}
Thank you
I believe there is no builtin function to do the same, so it will need to be implemented with a loop.
Something along the lines of:
Public Function rot47(str)
fromChars = "!""#$%&\'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
toChars = "PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!""#$%&\'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNO"
rot47 = ""
For i = 1 To Len(str)
Position = InStr(fromChars, Mid(str, i, 1))
If Position = 0 Then
rot47 = rot47 & Mid(str, i, 1)
Else
rot47 = rot47 & Mid(toChars, Position, 1)
End If
Next
End Function
Related
I am getting 'Invalid procedure call or argument: 5' error on the following piece of code bolded below. It has run successfully in the past with strings that longer than the one causing the error today. I have tried to include all pertinent information for troubleshooting. I did not write this code so I am lost as to what the issue could be. Any help would be appreciated to resolve the error. Debugger highlights the commented line below.
If ActiveWorkbook.Sheets("Macro-Tool").Cells(6, 5) <> "" Then
testsetfolderpath = ActiveWorkbook.Sheets("Macro-Tool").Cells(6, 5)
'get project name from Test SetFolder Path.
'cycle_int = InStrRev(testsetfolderpath, "\")
'test_mode = VBA.Right(testsetfolderpath, Len(testsetfolderpath) - cycle_int)
'inter_str = VBA.Left(testsetfolderpath, cycle_int - 1)
'inter_str1 = VBA.Left(inter_str, InStrRev(inter_str, "\") - 1)
'release_name = VBA.Right(inter_str1, Len(inter_str1) - InStrRev(inter_str1, "\"))
release_name = "^" + ActiveWorkbook.Sheets("Macro-Tool").Cells(7, 5) + "^"
Set tsetfactory = QcConnection.TestSetFactory
Set LabFilter = tsetfactory.Filter
LabFilter.Filter("CY_FOLDER_ID") = "^" + testsetfolderpath + "^"
Set testsets = LabFilter.NewList
i = 3
For Each tset In testsets
Set tsetfold = tset.TestSetFolder
' Error here ----------------------------------------------
parse_str = Right(tsetfold.Path, Len(tsetfold.Path) - Len(testsetfolderpath) - 1)
' ---------------------------------------------------------
pos1 = InStr(1, parse_str, "\")
If pos1 = 0 Then
func_area = parse_str
bus_process = parse_str
stream = parse_str
Else
func_area = Left(parse_str, pos1 - 1)
bus_process = Right(parse_str, Len(parse_str) - pos1)
pos2 = InStr(1, bus_process, "\")
If pos2 = 0 Then
stream = bus_process
Else
stream = Left(bus_process, pos2 - 1)
End If
End If
Additional information within the code that may be useful for troubleshooting:
Public field_names, parse_str, testsetfolderpath, inter_str1, test_mode, cycle_folder As String
Public tsetfold As TestSetFolder
testsetfolderpath = Root\System Test\2021 Projects\XXXX123456 Xxxxxxx Xxxxxxxxxxxxxx XX Xxxxxxxxxxxxxx - Xxxxxx X\Xxxxxx X.X_XXX
Perplexed by the function of using a second = sign in vba. eg. s = Int(xVal) + (xVal = n + 1)
I had been deciphering some code and came across the following line which is perplexing me somewhat and despite some extensive research and debugging I seem to be struggling to find the answer:
s = Int(xVal) + (xVal = n + 1)
and
p(i, 3) = A(i)(s + 3 + (s = n)) + (s = n) * (p(i, 1) - p(i, 2))
My question is what is the function of the comparisons within the parentheses after the first assignment = sign?
TIA
(s = n)
If both s and n have the same value then this evaluates to True, which can be coerced to its underlying value of -1 by other arithmetic operations.
Eg:
? True * 1 '>> -1
? False * 1 '>> 0
So this:
s = Int(xVal) + (xVal = n + 1)
is like writing:
If xVal = n + 1 Then
s = Int(xVal) + -1
else
s = Int(xVal) + 0
end if
or:
s = Int(xVal) + IIf(xVal = n + 1, -1, 0)
I need to remove the numeric part at the end of a string. Here are some examples:
"abcd1234" -> "abcd"
"a3bc45" -> "a3bc"
"kj3ih5" -> "kj3ih"
You get the idea.
I implemented a function which works well for this purpose.
Function VarStamm(name As String) As String
Dim i, a As Integer
a = 0
For i = Len(name) To 1 Step -1
If IsNumeric(Mid(name, i, 1)) = False Then
i = i + 1
Exit For
End If
Next i
If i <= Len(name) Then
VarStamm = name.Substring(0, i - 1)
Else
VarStamm = name
End If
End Function
The question is: is there any faster (more efficient in speed) way to do this? The problem is, I call this function within a loop with 3 million iterations and it would be nice to have it be more efficient.
I know about the String.LastIndexOf method, but I don't know how to use it when I need the index of the last connected number within a string.
You can use Array.FindLastIndex and then Substring:
Dim lastNonDigitIndex = Array.FindLastIndex(text.ToCharArray(), Function(c) Not char.IsDigit(c))
If lastNonDigitIndex >= 0
lastNonDigitIndex += 1
Dim part1 = text.Substring(0, lastNonDigitIndex)
Dim part2 = text.Substring(lastNonDigitIndex)
End If
I was skeptical that the Array.FindLastIndex method was actually faster, so I tested it myself. I borrowed the testing code posted by Amessihel, but added a third method:
Function VarStamm3(name As String) As String
Dim i As Integer
For i = name.Length - 1 To 0 Step -1
If Not Char.IsDigit(name(i)) Then
Exit For
End If
Next i
Return name.Substring(0, i + 1)
End Function
It uses your original algorithm, but just swaps out the old VB6-style string methods for newer .NET equivalent ones. Here's the results on my machine:
RunTime :
- VarStamm : 00:00:07.92
- VarStamm2 : 00:00:00.60
- VarStamm3 : 00:00:00.23
As you can see, your original algorithm was already quite well tuned. The problem wasn't the loop. The problem was Mid, IsNumeric, and Len. Since Tim's method didn't use those, it was much faster. But, if you stick with a manual for loop, it's twice as fast as using Array.FindLastIndex, all things being equal
Given your function VarStamm and Tim Schmelter's one named VarStamm2, here is a small test performance I wrote. I typed an arbitrary long String with a huge right part, and ran the functions one million times.
Module StackOverlow
Sub Main()
Dim testStr = "azekzoerjezoriezltjreoitueriou7657678678797897898997897978897898797989797"
Console.WriteLine("RunTime :" + vbNewLine +
" - VarStamm : " + getTimeSpent(AddressOf VarStamm, testStr) + vbNewLine +
" - VarStamm2 : " + getTimeSpent(AddressOf VarStamm2, testStr))
End Sub
Function getTimeSpent(f As Action(Of String), str As String) As String
Dim sw As Stopwatch = New Stopwatch()
Dim ts As TimeSpan
sw.Start()
For i = 1 To 1000000
f(str)
Next
sw.Stop()
ts = sw.Elapsed
Return String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10)
End Function
Function VarStamm(name As String) As String
Dim i, a As Integer
a = 0
For i = Len(name) To 1 Step -1
If IsNumeric(Mid(name, i, 1)) = False Then
i = i + 1
Exit For
End If
Next i
If i <= Len(name) Then
VarStamm = name.Substring(0, i - 1)
Else
VarStamm = name
End If
End Function
Function VarStamm2(name As String) As String
Dim lastNonDigitIndex = Array.FindLastIndex(name.ToCharArray(), Function(c) Not Char.IsDigit(c))
If lastNonDigitIndex >= 0 Then
lastNonDigitIndex += 1
Return name.Substring(0, lastNonDigitIndex)
End If
Return name
End Function
End Module
Here is the output I got:
RunTime :
- VarStamm : 00:00:38.33
- VarStamm2 : 00:00:02.72
So yes, you should choose his answer, his code is both pretty and efficient.
I have a string. I need to compare 1st character of the string to a specific character. Below is the C# code.
String URL = "www.vulnuryrweb.com";
bool isValid = URL[0] == '/'
&& URL[1] != '/'
&& URL[1] != '\\';
What will be VB-Script equivalent of above code?
URL = "www.vulnuryrweb.com"
char1 = Left(URL, 1)
char2 = Mid(URL, 2, 1)
isValid = ( char1 = "/" And char2 <> "/" And char2 <> "\" )
MsgBox isValid
Update: It can be simplified with the Like operator :
URL = "www.vulnuryrweb.com"
isValid = URL Like "/[/\]*"
Debug.Print isValid
[/\] checks if the second character is / or \, and * matches 0 or more characters.
According to http://www.w3schools.com/asp/func_mid.asp you will need to do
URL = "www.vulnuryrweb.com";
firstLetter = Mid(URL,1,1)
which will return w in this case
use the Mid function to get the first n chars of a string, then compare this to the results you want to check for
Dim isValid
isValid = (Mid(URL, 1, 1) = "/" And Mid(URL, 2, 1) <> "/" And Mid(URL, 2, 1) <> "\")
Note that Mid uses a 1 based index for characters (index 1 is the first char) whereas C# uses 0 based (url[0] is the first char)
I have string
'TEST1, TEST2, TEST3'
I want to have
'TEST1,TEST2,TEST3'
Is in powerbuilder is a function like replace, substr or something?
One way is to use the database since you probably have an active connection.
string ls_stringwithspaces = "String String String String"
string ls_stringwithnospace = ""
string ls_sql = "SELECT replace('" + ls_stringwithspaces + "', ' ', '')"
DECLARE db DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql USING SQLCA;
OPEN DYNAMIC db;
IF SQLCA.SQLCode > 0 THEN
// erro handling
END IF
FETCH db INTO :ls_stringwithnospace;
CLOSE db;
MessageBox("", ls_stringwithnospace)
Sure there is (you could have easily found it in the help) but it is not quite helpful, though.
Its prototype is Replace ( string1, start, n, string2 ), so you need to know the position of the string to replace before calling it.
There is a common wrapper for this that consists of looping on pos() / replace() until there is nothing left to replace. The following is the source code of a global function:
global type replaceall from function_object
end type
forward prototypes
global function string replaceall (string as_source, string as_pattern, string as_replace)
end prototypes
global function string replaceall (string as_source, string as_pattern, string as_replace);//replace all occurences of as_pattern in as_source by as_replace
string ls_target
long i, j
ls_target=""
i = 1
j = 1
do
i = pos( as_source, as_pattern, j )
if i>0 then
ls_target += mid( as_source, j, i - j )
ls_target += as_replace
j = i + len( as_pattern )
else
ls_target += mid( as_source, j )
end if
loop while i>0
return ls_target
end function
Beware that string functions (searching & concatenating) in PB are not that efficient, and an alternative solution could be to use the FastReplaceall() global function provided by the PbniRegex extension. It is a c++ compiled plugin for PB classic from versions 9 to 12.
I do that:
long space, ll_a
FOR ll_a = 1 to len(ls_string)
space = pos(ls_string, " ")
IF space > 0 THEN
ls_string= Replace(ls_string, space, 1, "")
END IF
NEXT