Android Question Count Special Characters In String

ronovar

Active Member
Licensed User
Longtime User
I have string:

B4X:
Dim Name As String

Name = "A,B,C,D,E"

Log(Name.CharactersCount(",")) ' Need To Output 4

How can i do that in B4A without using For Loop? Is there a special library or short version?

I need to cut my string after second "," but need to know how many characters is in string because if i use directly SubString2 and cut after second "," and there is only one "," function will get error code so i need to know exactly how many "," is in the string.
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I have string:

B4X:
Dim Name As String

Name = "A,B,C,D,E"

Log(Name.CharactersCount(",")) ' Need To Output 4

How can i do that in B4A without using For Loop? Is there a special library or short version?

I need to cut my string after second "," but need to know how many characters is in string because if i use directly SubString2 and cut after second "," and there is only one "," function will get error code so i need to know exactly how many "," is in the string.

Why do you want to avoid a for loop?
I would guess using that it is lot faster than using for example Regex.Split.
Not tested.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I have string:

B4X:
Dim Name As String

Name = "A,B,C,D,E"

Log(Name.CharactersCount(",")) ' Need To Output 4

How can i do that in B4A without using For Loop? Is there a special library or short version?

I need to cut my string after second "," but need to know how many characters is in string because if i use directly SubString2 and cut after second "," and there is only one "," function will get error code so i need to know exactly how many "," is in the string.

Another option is to adjust the Substring2 function for example:

B4X:
Sub SubStr2(str As String, iStart As Int, iEnd As Int) As String
 If str.Length < iEnd Or str.Length < iStart + 1 Then
  Return ""
 End If
 Return str.SubString2(iStart, iEnd)
End Sub

RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
For the life of me I do not understand why someone overshadows an answer without giving the person who created the thread a chance to comment, accept or refute the original answer, particularly when they have not tested their code.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
For the life of me I do not understand why someone overshadows an answer without giving the person who created the thread a chance to comment, accept or refute the original answer, particularly when they have not tested their code.

Isn't that a bit over the top? I am sure the OP can judge for himself.
I have tested and found a simple loop working on a byte array about 4 to 5 times faster.
Of course speed is not relevant if you are dealing with small strings.


B4X:
Private lStartTime(10) As Long

Public Sub StartSW(iIndex As Int)
 lStartTime(iIndex) = DateTime.Now
End Sub

Public Sub StopSW(iIndex As Int) As Long
 Return DateTime.Now - lStartTime(iIndex)
End Sub

Sub MakeString2(btByte1 As Byte, btByte2 As Byte, lNum As Long) As String
 
 Dim i As Long
 Dim arrBytes(lNum * 2) As Byte
 
 For i = 0 To lNum - 1 Step 2
  arrBytes(i) = btByte1
 Next
 
 For i = 1 To lNum - 1 Step 2
  arrBytes(i) = btByte2
 Next
 
 Return BC.StringFromBytes(arrBytes, "ASCII")

End Sub

Sub TestCountChar
 
 Dim i As Long
 Dim str As String
 Dim lCount As Long
 Dim arrBytes() As Byte
 
 str = MakeString2(97, 44, 10000000)
 
 General.StartSW(0)
 Dim arrName() As String = Regex.Split(",", str)
 lCount = arrName.Length - 1
 Log("count: " & lCount & "  time: " & General.StopSW(0))
 
 General.StartSW(0)
 arrBytes = str.GetBytes("ASCII")
 lCount = 0
 For i = 0 To arrBytes.Length - 1
  If arrBytes(i) = 44 Then
  lCount = lCount + 1
  End If
 Next
 Log("count: " & lCount & "  time: " & General.StopSW(0))
 
End Sub


RBS
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
B4X:
Dim Name As String= "A,B,C,D,E"
    Dim arrName() As String=Regex.Split(",",Name)
    Log($"Number of commas: ${arrName.Length-1}"$)  'displays 4
Thanks this works very well..i have only two strings that have around from 1 to 38 "," special characters in string and this function works without error.
Thanks.
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
Ok..i added tzo program and i test around 20 items with that string and all works..apk does not crash so all is fine.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Sure, but probably a bit of an overkill for the OPs question.

Not sure, counting a character in a string is a common thing, so you can make a function.
Actually, if the characters to count are further apart then the Regex.Split method will be faster than the string replace method.
Try for example with "abc,abc" repeated x times:

B4X:
Sub MakeString3(str As String, lNum As Long) As String
 Dim i As Long
 Dim n As Long
 Dim x As Long
 Dim z As Long
 Dim arrBytes1() As Byte
 arrBytes1 = str.GetBytes("ASCII")
 x = str.Length - 1
 Dim arrBytes2(str.Length * lNum) As Byte
 For i = 1 To lNum
  For n = 0 To x
   arrBytes2(z) = arrBytes1(n)
   z = z + 1
  Next
 Next
 Return BC.StringFromBytes(arrBytes2, "ASCII")
End Sub

str = MakeString3("abc,abc", 1000000)


RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Thanks this works very well..i have only two strings that have around from 1 to 38 "," special characters in string and this function works without error.
Thanks.

Also if you have a string like for example "abc," repeated x times then the Regex.Split method will count one too little.

RBS
 
Upvote 0
Top