Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

This pasky char(173) 1

Status
Not open for further replies.

IlyaRabyy

Programmer
Nov 9, 2010
568
US
Colleagues,
Hit a roadblock with generic wrapper-function CharTran() (equivalent of VFP's CHRTRAN()) around the built-in Replace() function.
And that's with that char #173.
Dunno why, but the line
Code:
sRetStr = Replace(sRetStr, cChar2Change, "", 1, -1, iCompMethod)
renders sRetStr blank.
Initially, the sRetStr was "Proctor & Gamble @ 1234 W. St. #567, New York, NY 20000, U.S.A." (This's just a test string, not a real one.)
The task was to remove all non-alpha/numeric chars, that includes all the 2nd part of ASCII/ANSI table.
So I go in a For...Next cycle running that line above for every "bad" char. And everything worked, until cChar2Chage hit that Chr(173)... Boom! sRetStr == Space(0) - ?!?!?
I have it circumvented in the code, of course:
Code:
If AscW(cChar2Change) = 173 Then Continue For
but that's a bandaid on a mortal wound.
Any advise on more enlightened resolution for this problem?

P.S. If you need me to, I can post here the entire code of this my lil' function.



Regards,

Ilya
 
It would be nice to see the entire code, and a little explanation of what you wan to achieve. You state that you want to "remove all non-alpha/numeric chars", right?

I would assume you want to leave all:
Char(48) to Char(57) (numbers from 0 to 9)
Char(65) to Char(90) (upper letters A to Z)
Char(97) to Char(122) (lower letters a to z)
maybe change '&' to 'and'... [ponder]
and get rid of everything else.

---- Andy

There is a great need for a sarcasm font.
 
Given yor tesdt string does not appear to actually contain Chr(173), I think we need somewhat more info ...
 
change '&' to 'and'... [ponder]
and get rid of everything else."
Close, but not exactly correct: '&' is to be changed to ' ' (one space, Chr(32)).
Other than that - Yes, Sir!

Regards,

Ilya
 
I can post here the entire code of this my lil' function" so, where is the code?

Just a guess here (since I do not have your specifications):

Code:
.
    Public Function FixMyString(ByRef strIn As String) As String
        Dim strOut As String

        For i As Integer = 1 To Strings.Len(strIn)
            Select Case Strings.Mid(strIn, i, 1)
                Case Strings.Chr(32) To Strings.Chr(59),
                    Strings.Chr(65) To Strings.Chr(90),
                    Strings.Chr(97) To Strings.Chr(122)

                    strOut &= Strings.Mid(strIn, i, 1)
            End Select
        Next

        Return strOut
    End Function

[tt]Strings.Chr[/tt] numbers based on this list - add or eliminate as you see fit.
---- Andy

There is a great need for a sarcasm font.
 
Or use regular expressions, e.g:

Code:
[blue]Imports System.Text.RegularExpressions
Module UtilityFunctions
    Public Function CleanString(DirtyString As String) As String
        CleanString = Regex.Replace(Replace(DirtyString, "&", " "), "[^\w\s+]", "")
        CleanString = Regex.Replace(CleanString, "\s+", " ")
    End Function
End Module[/blue]
 
OK, as promised:

Code:
Function CharTran(ByVal sTargetStr As String, ByVal sTargetChars As String, _
                            Optional ByVal sReplacementChars As String = "", Optional ByVal iCompMethod As Integer = 0) As String
   '====================================================================================================================================
   ' Purpose       : Replaces the targeted existing character(s) in the source string with corresponding ones in the given replacement
   '                 string.
   ' Description   : Checks if the passed parameters' data types match those of the Function's arguments; if not – throws error message 
   '                 and returns empty string, except the case when Replacement Chars is blank – then Target String returned unchanged.
   '                 Runs built-in String.Replace() system function consequently for each char in the Target Chars string to replace 
   '                 those with corresponding Replacement Char.
   ' Parameters    : Target string that needs to be updated;
   '                 String of the characters to be replaced;
   '                 String of the replacement characters;
   '                 Comparison method.
   ' Returns       : Updated string as String.
   ' Side effects  : None.
   ' Notes         : 1. Generic, complies with .NET Framework ver. 1.1 and higher.
   '                 2. If the Replacement Chars string is empty (default) – all the characters of the Target Chars in the Target 
   '                    string will be deleted, empty string returned.
   '                 3. If Comparison method is 0 (default) – the comparison will be case-sensitive, if 1 – case-insensitive.
   '                 4. All characters in the Target String matching those in the Replacement String will be replaced. Example:
   '                    sTargetStr = "Aha", sTargetChars = "a", sReplacementChars = "u", iCompMethod = 1 (case-insensitive) => "uhu"
   '                          - '' -             - '' -                - '' -            iCompMethod = 0 (case-sensitive) => "Ahu"
   '                 5. If a Char member of Target Chars set not found in the Target String - it's ignored.
   '                 6. If a Char member of Target Chars set found in the Target String but has no Replacement Char of the corresponding
   '                    sequential number (e.g. #5 in Target Chars, but there are only 4 Replacement Chars) - it's ignored.
   ' Author        : Ilya I. Rabyy
   ' Revisions     : 2019-12-19 by Ilya – started 1st draft.
   '====================================================================================================================================
   ' Memvars' declaration
   Dim sMsg As String, lGoOn As Boolean, sRetStr As String

   lGoOn = True ' Initially
   sRetStr = "" ' Initially

   ' Non-optional parameters' verification
   If VarType(sTargetStr) <> vbString Then
      sMsg = "Invalid parameter passed: sTargetStr must be of type String!"
      lGoOn = False
   ElseIf String.IsNullOrEmpty(sTargetStr) Then
   ' No need to scream, just return that blank string
      lGoOn = False
   ElseIf VarType(sTargetChars) <> vbString Then
      sMsg = "Invalid parameter passed: sTargetChars must be of type String!"
      lGoOn = False
   ElseIf String.IsNullOrEmpty(sTargetChars) Then
   ' Same as with Target String: no screaming, just return the original string
      sRetStr = sTargetStr
      lGoOn = False
   End If

   If lGoOn = False Then
      Return sRetStr
   End If

   ' Special case: calling proc wants to change all the chars in given string to the same single char,
   ' e.g. "you" to "U", and the Replacement string is just "U"
   If Len(sReplacementChars) = 1 Then sReplacementChars = StrDup(Len(sTargetChars), sReplacementChars)

   ' Done with parameters' verification part.
   ' More memvars' declaration
   Dim iSrcPos As Integer, cChar2Change As Char, iStrLen As Integer

   sRetStr = sTargetStr ' Initially
   iStrLen = Len(sTargetChars)

   ' Cycle thru the targeted chars and replace them with their counterparts from Replacement string
   For iSrcPos = 1 To iStrLen
      cChar2Change = Mid(sTargetChars, iSrcPos, 1)

      If AscW(cChar2Change) = 173 Or AscW(cChar2Change) = 178 Then Continue For
      ' Gotta skip char 173 coz it nullifies the whole string (why?), and shar 178 cuts off the last char in the sRetStr (why?)

      'Debug, 2019-12-23 - losing the last character in the given string - ?
      If Asc(cChar2Change) = 128 Then Stop ' The only Q. mark in the last sequence "?_V01"

      If String.IsNullOrEmpty(sReplacementChars) Then ' The calling proc just wants to delete this Char from the given string - OK!
         sRetStr = Replace(sRetStr, cChar2Change, "", 1, -1, iCompMethod)
      Else
         sRetStr = Replace(sRetStr, cChar2Change, IIf(iSrcPos <= Len(sReplacementChars), Mid(sReplacementChars, iSrcPos, 1), ""), 1, -1, iCompMethod)
      End If

    Next iSrcPos

   Return sRetStr
   End Function

The code that creates the targeted for replacement characters in the calling procedure:

Code:
   For J As Integer = 32 To 47
      sChr2Change = sChr2Change & Chr(J)
   Next J

   For J As Integer = 58 To 64
      sChr2Change = sChr2Change & Chr(J)
   Next J

   For J As Integer = 91 To 96
      sChr2Change = sChr2Change & Chr(J)
   Next J

   For J As Integer = 123 To 255
      sChr2Change = sChr2Change & Chr(J)
   Next J

This another "glitch" with Chr(178) was discovered just an hour ago (was doing step-by-step debugging).
Any advice would be greatly appreciated!

Regards,

Ilya
 
On refelection, your problem almost certainly boils down to this: A Binary comparison compares the numeric Unicode value of each character in each string. A Text comparison compares each Unicode character based on its lexical meaning in the current culture. Make sure you use vbBinaryCompare to avoid erasing the string.
 
That was it, colleague!
Thank you!
The following four "bad" chars are real bad when it's vbTextCompare (e.g. 1, case-insensitive): 173 nullifies the whole string, and 178, 182, 185 cut off the last char in the sRetStr.
When it's vbBinaryCompare (e.g. 0, case-sensitive) - it doesn't do it.
So, it strikes me as it's a glitch in the MS product. Well, this one's not the first and I suspect not the last such discrepancy. :-(
Anyway, that line in the function's code's For...Next cycle now is
Code:
If iCompMethod = vbTextCompare And (cASCII = 173 Or cASCII = 178 Or cASCII = 182 Or cASCII = 185) Then Continue For
Not exactly The Solution, a workaround rather, but what else can this humble one do? ;-)
Thanks to everybody for your help!
Case is closed.


Regards,

Ilya
 
>it strikes me as it's a glitch in the MS product


Not sure I agree. It is doing what it is supposed to, but the basic documentation doesn't explain just how complex string sorting (i.e. vbTextCompare) actually is (nor how the Replace function is using it), unless you start looking at some of the underlying sorting and locale documentation, e.g or
You've managed a partial work around in your code - but my question to you now is - do you really need to implement a version CHRTRAN, or do you just need to clean strings as discussed between you and Andrzejek? If the latter, have you then tried my code at all?
 
CHRTRAN() need I, young Skywalker... [lol] (Sorry, Master Yoda!)

(Just joking, no offense meant!)

Yes, we really need Char Tran here. Clients send their data strings in any imaginable (and even unimaginable) format and request that we follow their format - which's not always (if ever) possible. Let's say they send a branch number instead of the bank name, or dept. manager name instead of department name... and our processing system (3rd-party S/W + some custom-made by contractors one) requires it's own format... so we have to slice-n-dice-n-glue-it-back all the time. So, it's not just cleaning up "bad" chars.

Regards,

Ilya
 
Fine (although I'm not quite sure how a fairly simplistic character replacement function addresses any of the issues you highlight) - so a clone of FoxPro's CHRTRAN , or your CHARTRAN (which behaves somewhat differently from FoxPro's - and also doesn't quite behave the way your commented notes suggest)?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top