I would like to replace a comma in between two double quotes.
EXAMPLE:
Replace:
11/18/2015,15:27,1,103,3,,,197179,"Petco, Inc.",Amy,Jr,187.061,452.5,0,0,0,2.419,0,0,37.38,489.88`
With:
11/18/2015,15:27,1,103,3,,,197179,"Petco Inc.",Amy,Jr,187.061,452.5,0,0,0,2.419,0,0,37.38,489.88
NOTE: I still want to keep the bare commas I just want to replace any commas that are inside of the double quote "
I know I can replace the commas by doing this: strText = Replace(strText, ",", "")
but how do I do that in between the two double quotes only and not affect the other commas that are outside of the double quotes.
Tried this thanks to pee2pee but getting an error: Expected identifier
.Pattern = "/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g"
-------------------^
dim re
Set re = New RegExp
With re
.Pattern = "/(""".*?"""|[^""",\s]+)(?=\s*,|\s*$)/g"
.IgnoreCase = False
.Global = False
End With
Set re = Nothing
Thanks
1 - Classic one:
csv = "..." ' your lines
ReDim chars(Len(csv) - 1) 'array for output
wearein = False
For i = 1 To Len(csv)
chars(i-1) = Mid(csv, i, 1)
Select Case chars(i-1)
Case Chr(34) 'we're in
wearein = Not wearein
Case ","
If wearein Then chars(i-1) = ""
End Select
Next
newstr = Join(chars, "")
Response.Write newstr
2 - By using RegExp and a callback function :
Function ReplaceCallback(match, position, all)
ReplaceCallback = Replace(match, ",", "")
End Function
Set re = New RegExp
re.Pattern = """[^""]*,[^""]*"""
re.Global = True
csv = "..." 'your lines
newstr = re.Replace(csv, GetRef("ReplaceCallback")) 'replace done
Response.Write newstr
3 - By mixing MS JScript and VBScript:
<script language="JScript" runat="server">
function removeCommas(text){
return text.replace(/"[^"]*,[^"]*"/g, function(){return arguments[0].replace(/,/g, "")});
}
</script>
<%
csv = "..." 'your lines
Response.Write removeCommas(csv)
%>
The regex pattern you need would be something like
/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g
ONLY and ONLY in this case, you can use:
strText = Replace(strText, ", ", " ")
because you have just a space after the comma you need to replace.
An easy (but probably not that efficient) solution could be going one char at a time changing the comma if you passed an uneven amount of double quotes, finishing after the last double quote.
string origin = ""; //Your string to convert
int lastIndex = origin.LastIndexOf('"');
bool betweenQuotes = false;
for(int i = 0; i < lastIndex; i++)
{
if(origin[i] == '"')
betweenQuotes = !betweenQuotes;
if(origin[i] == ',' && betweenQuotes)
origin[i] = ' ';
}
Edit: You can't set a char like I did in the last row
origin[i] = ' ';
it won't work in c#.
put in that line this instead
origin = origin.Substring(0, i) + " " + origin.Substring(i + 1);
That solution was for C#, so I made a code in VB that does the same thing since as I understood online ASP works (or at least can work) with VB. (Sorry, but it's my first time working with classic asp and VB). But this code in VB is working for me.
Dim origin As String = "11/18/2015,15:27,1,103,3,,,197179,fPetco, Inc.f,Amy,Jr,187.061,452.5,0,0,0,2.419,0,0,37.38,489.88"
Dim lastIndex As Integer = 0
Dim betweenQuotes As Boolean = False
For i As Integer = 0 To origin.Length - 1
If origin(i) = "f" Then
lastIndex = i
End If
Next
For i As Integer = 0 To lastIndex
If origin(i) = "f" Then
betweenQuotes = Not betweenQuotes
End If
If origin(i) = "," AndAlso betweenQuotes Then
origin = origin.Substring(0, i) + " " + origin.Substring(i + 1)
End If
Next
I just replaced the double quotes with the f char since I have no idea how to put special chars in a string in VB. but this code replaces the comma only between the Fs, so it should be ok.
I also made a JS version, cause that would work everywhere on the web doesn't matter what language you used to create the page.
var origin = "";
var lastIndex = 0;
var betweenQuotes = false;
for (var i = 0; i < origin.length ; i++)
if (origin[i] == '"')
lastIndex = i;
for(i = 0; i < lastIndex; i++)
{
if (origin[i] == '"')
betweenQuotes = !betweenQuotes;
if (origin[i] == ',' && betweenQuotes) {
origin = origin.substr(0, i) + " " + origin.substr(i + 1, origin.length - i - 1);
}
}
Related
I'm trying to find a better solution for the integration of a string and generate a new field with the maximum value of the parameter. #AutomatedChaos has helped me with the following code. But I need a better solution for the flexibility of the code.
First string split by * (stars) and I want to merge all items and create a new string with max value.
fString = "projects#dnProjectsPatterning=0|dnProjectsSendReport=1#workplans#dnWorkplansAdd=0|dnWorkplansGrouping=1*projects#dnProjectsPatterning=1|dnProjectsSendReport=3#workplans#dnWorkplansAdd=1|dnWorkplansGrouping=0*projects#dnProjectsPatterning=5|dnProjectsSendReport=1#workplans#dnWorkplansAdd=0|dnWorkplansGrouping=2"
Set dict = CreateObject("Scripting.Dictionary")
Set re = New RegExp
re.Global = True
re.Pattern = "(\w+)=(\d+)"
Set matches = re.Execute(fString)
For Each match In matches
key = match.Submatches(0)
value = CInt(match.Submatches(1))
If dict.Exists(key) Then
If value < dict.Item(key) then
value = dict.Item(key)
End If
End If
dict.Item(key) = value
Next
For Each key In dict
MsgBox key & "=" & dict.Item(key)
Next
' output:
' dnProjectsPatterning=5
' dnProjectsSendReport=3
' dnWorkplansAdd=1
' dnWorkplansGrouping=2
I want to generate this string:
newString = "projects#dnProjectsPatterning=5|dnProjectsSendReport=3#workplans#dnWorkplansAdd=1|dnWorkplansGrouping=2"
Please note for projects# and workplans#, the two are split by #.
Here's another example that will work if the parameters are always ordered as shown.
The following code simply treats all separators except * as part of the keys. You can look at this regexr shot to see how the pattern works.
fString = "projects#dnProjectsPatterning=0|dnProjectsSendReport=1#workplans#dnWorkplansAdd=0|dnWorkplansGrouping=1*projects#dnProjectsPatterning=1|dnProjectsSendReport=3#workplans#dnWorkplansAdd=1|dnWorkplansGrouping=0*projects#dnProjectsPatterning=5|dnProjectsSendReport=1#workplans#dnWorkplansAdd=0|dnWorkplansGrouping=2"
Set params = CreateObject("Scripting.Dictionary")
With (New RegExp)
.Global = True
.Pattern = "([^=*]*)=(\d+)"
For Each match In .Execute(fString)
key = match.Submatches(0)
val = match.Submatches(1)
If params.Exists(key) Then
If val > params(key) Then params(key) = val
Else
params.Add key, val
End If
Next
End With
'temporary str dictionary to generate string
Set str = CreateObject("Scripting.Dictionary")
For Each key In params
'prepend key + "=" into items to generate merged string
str.Add key, key & "=" & params(key)
Next
newString = Join(str.Items, "") 'joining items
WScript.Echo newString
'normalize params' keys
For Each key In params
If Left(key, 1) = "|" Or Left(key, 1) = "#" Then
params.Key(key) = Mid(key, 2)
End If
Next
'lookup for `dnProjectsSendReport` parameter
WScript.Echo params("dnProjectsSendReport") 'must print 3
I find a solution:
'target = "projects#param1={param1}|param2={param2}#workplans#param3={param3}|param4={param4}..."
f_AccessArray = "projects#dnProjectsPatterning=0|dnProjectsSendReport=1#workplans#dnWorkplansAdd=0|dnWorkplansGrouping=1*projects#dnProjectsPatterning=1|dnProjectsSendReport=3#workplans#dnWorkplansAdd=1|dnWorkplansGrouping=0*projects#dnProjectsPatterning=5|dnProjectsSendReport=1#workplans#dnWorkplansAdd=0|dnWorkplansGrouping=2"
arrAccessPack = Split(f_AccessArray,"*")
endString = Split(arrAccessPack(0),"#")
nArrString = ""
for i = 0 to UBound(endString)
if i < UBound(endString) then strHash = "#" else strHash = ""
part1 = Split(endString(i),"#")(0)
part2 = Split(Split(endString(i),"#")(1),"|")
newParams = ""
for j = 0 to UBound(part2)
if j < UBound(part2) then strPipe = "|" else strPipe = ""
param = Split(part2(j),"=")(0)
newParams = newParams & param&"={"¶m&"}" & strPipe
next
nArrString = nArrString & part1&"#"&newParams & strHash
next
MergeAccessArray = MergerParams(f_AccessArray,nArrString)
Function MergerParams(fStr,fTarget)
Set dict = CreateObject("Scripting.Dictionary")
Set re = New RegExp
re.Global = True
re.Pattern = "(\w+)=(\d+)"
Set matches = re.Execute(fStr)
for each match in matches
key = match.Submatches(0)
value = cint(match.Submatches(1))
If dict.Exists(key) Then
If value < dict.Item(key) then
value = dict.Item(key)
End If
End If
dict.Item(key) = value
next
target = fTarget
for each key in dict
target = Replace(target, "{" & key & "}", dict.Item(key))
Next
MergerParams = target
End Function
Ok so I'm working on a program that parses input in the textbox and finds a delimiter such as a comma, space, or a line pressed using enter key and extracting each word before each delimiter and posting it in the listbox. I keep getting errors though.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim delimiter As String = ""
Dim oldIndex As Integer = 0
Dim newIndex As Integer = 0
Dim length As Integer = 0
Dim tempString As String = ""
Dim tempWord As String = ""
Dim advanceSize As Integer = 0
If RadioButton1.Checked = True Then
delimiter = ","
advanceSize = 1
tempString = TextBox1.Text
length = tempString.Length
Do While oldIndex < length
newIndex = tempString.IndexOf(delimiter)
tempWord = Mid(tempString, oldIndex, newIndex)
tempWord.Trim()
oldIndex = newIndex + advanceSize
ListBox1.Items.Add(tempWord)
Loop
ElseIf RadioButton2.Checked = True Then
delimiter = vbCrLf
advanceSize = 2
tempString = TextBox1.Text
length = tempString.Length
Do While oldIndex < length
newIndex = tempString.IndexOf(delimiter)
newIndex = tempString.IndexOf(delimiter)
tempWord = Mid(tempString, oldIndex, newIndex)
tempWord.Trim()
oldIndex = newIndex + advanceSize
ListBox1.Items.Add(tempWord)
Loop
ElseIf RadioButton3.Checked = True Then
delimiter = " "
advanceSize = 1
tempString = TextBox1.Text
length = tempString.Length
Do While oldIndex < length
newIndex = tempString.IndexOf(delimiter)
newIndex = tempString.IndexOf(delimiter)
tempWord = Mid(tempString, oldIndex, newIndex)
tempWord.Trim()
oldIndex = newIndex + advanceSize
ListBox1.Items.Add(tempWord)
Loop
Else
Exit Sub
In the first line read, the value of oldindex is zero. The Mid function requires a number greater than zero for the second parameter because, unlike the string.substring method, it is one-based rather than zero-based. The error will be resolved if you initialize oldindex to 1.
Incidentally, the third parameter of mid (and .substring) is length, not an ending index.
May I suggest an alternative which achieves the goal of your question? There is a String.Split function which you can use. It's a bit fiddly, as to split on a string you need to use an array of strings (there can be just one in the array, which is all we need) and you have to specify a StringSplitOptions value, but apart from that it is easy to use:
Private Sub bnSplitData_Click(sender As Object, e As EventArgs) Handles bnSplitData.Click
Dim txt = tbDataToSplit.Text
Dim delimiter As String() = Nothing
' select case true is an easy way of looking at several options:
Select Case True
Case rbCommas.Checked
delimiter = {","}
Case rbNewLines.Checked
delimiter = {vbCrLf}
Case rbSpaces.Checked
delimiter = {" "}
Case Else ' default value
delimiter = {","}
End Select
Dim parts = txt.Split(delimiter, StringSplitOptions.RemoveEmptyEntries)
' get rid of the old entries
ListBox1.Items.Clear()
' add the new entries all in one go
ListBox1.Items.AddRange(parts)
End Sub
Please note how I gave the controls (except ListBox1) meaningful names - it makes referring to the correct one much easier.
I have to extract the integer value from a string.
Its actually an amount field.
Say string can be 000000000000512 or 0000040000000
I want only the integer value from this string i.e.; 512/ 40000000
Please help with this in VB scripting
CInt("000000000000512")
See conversion functions: http://msdn.microsoft.com/en-us/library/s2dy91zy.aspx
Use Clng if you expect to have large numbers, as already pointed out in a comment:
Clng("000000004000512")
otherwise you'll have an overflow, as variant's subtype int is 16 bit in vbscript
This will work even with a crazy long number
Function RemoveLeadingZeroes(ByVal str)
Dim tempStr
tempStr = str
While Left(tempStr,1) = "0" AND tempStr <> ""
tempStr = Right(tempStr,Len(tempStr)-1)
Wend
RemoveLeadingZeroes = tempStr
End Function
strNewFileName = RemoveLeadingZeroes("0009283479283749823749872392384")
Use the Absolute Value of the number.
http://ss64.com/vb/abs.html
Var = ABS(Var)
I've used this technique before:
replace the zeros with spaces
left trim
replace the spaces with zeros
Replace(LTrim(Replace(str, "0", " ")), " ", "0")
Note, this doesn't work if str has meaningful spaces in it.
Function TrimLeadingZeros(value)
TrimLeadingZeros = value
while left(TrimLeadingZeros, 1) = "0" and TrimLeadingZeros <> "0"
TrimLeadingZeros = mid(TrimLeadingZeros, 2)
wend
End Function
or
Function TrimLeadingZeros(value)
dim i
i = 1
while i < len(value) and mid(value,i,1) = "0"
i = i + 1
wend
TrimLeadingZeros = mid(value, i)
End Function
Using regex:
Regex.Replace("000000000000512", "^0+", "") ' returns "512"
Regex.Replace("0000040000000", "^0+", "") ' returns "40000000"
In case your string includes digits and characters, use a Do While statement:
string = "00000456ABC"
Do While Left(string, 1) = "0"
string = Right(string, (Len(string)-1))
Loop
Function TrimLZ(str)
If Left(str, 1) = "0" Then
TrimLZ = TrimLZ(Mid(str, 2, Len(str)))
Else
TrimLZ = str
End If
End Function
I have an old function in VBScript for Classic ASP that strips out illegal characters when a form is submitted, but it's also stripping out foreign characters and replacing them with junk like A*#L, etc.
The function looks like this:
Private Function stripillegal(fieldcontents)
if isnull(fieldcontents) then
stripillegal = ""
else
Dim stripped, stripillegal_c, stripillegal_i
stripped = ""
if isempty(fieldcontents) then fieldcontents = ""
fieldcontents = CStr( fieldcontents )
fieldcontents = Trim( fieldcontents )
if Len(fieldcontents)>0 then
for stripillegal_i = 1 to Len(fieldcontents)
stripillegal_c = asc(mid(fieldcontents, stripillegal_i, 1))
select case stripillegal_c
case 39
stripped = stripped & "'"
case 37
stripped = stripped & "%"
case 34 ' quote (34)
stripped = stripped & """
case else
stripped = stripped & chr(stripillegal_c)
end select
' response.write stripped & "<br>"
next
end if
stripped = trim(stripped)
while Right(stripped, 1) = chr(13) OR Right(stripped, 1) = chr(10)
stripped = left(stripped, len(stripped)-1)
wend
stripillegal = stripped
end if
End Function
I'm wondering how to tell it to allow foreign characters like those found in French or Spanish.
Regular Expressions can clean these strings up nicely while avoiding foreign characters.
More specificly, this function:
Function strClean (strtoclean)
Dim objRegExp, outputStr
Set objRegExp = New Regexp
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = "[(?*"",\\<>&#~%{}+_.#:\/!;]+"
outputStr = objRegExp.Replace(strtoclean, "-")
objRegExp.Pattern = "\-+"
outputStr = objRegExp.Replace(outputStr, "-")
strClean = outputStr
End Function
Someone posted a great little function here the other day that separated the full path of a file into several parts that looked like this:
Function BreakDown(Full As String, FName As String, PName As String, Ext As String) As Integer
If Full = "" Then
BreakDown = False
Exit Function
End If
If InStr(Full, "\") Then
FName = Full
PName = ""
Sloc% = InStr(FName, "\")
Do While Sloc% <> 0
PName = PName + Left$(FName, Sloc%)
FName = Mid$(FName, Sloc% + 1)
Sloc% = InStr(FName, "\")
Loop
Else
PName = ""
FName = Full
End If
Dot% = InStr(Full, ".")
If Dot% <> 0 Then
Ext = Mid$(Full, Dot%)
Else
Ext = ""
End If
BreakDown = True
End Function
However if the line continues past that point it counts it as part of the extension, is there anyway to make this only count to 3 characters after the last period in a string?
Dot% = InStrRev(Full, ".") ' First . from end of string
If Dot% <> 0 Then
Ext = Mid$(Full, Dot%, 3)
Else
Ext = ""
End If
Mid$ syntax: Mid(string, start[, length])
If you just have blank characters then just add this as the first line
Full = Trim(Full)
If you have other characters then
Change:
Ext = Mid$(Full, Dot%)
to:
Ext = Mid$(Full, Dot%, 3)