1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

@count to count commas

Discussion in 'Support' started by Rick Reinckens, Feb 24, 2015.

  1. Rick Reinckens

    Joined:
    Oct 18, 2009
    Messages:
    96
    Likes Received:
    4
    How can I accurately count commas in a string, preferably with @count?

    Basically, I have some strings that should not contain commas but sometimes do. I can convert any commas to spaces with @replace and then replace any double spaces with a single space.

    But, if there are no commas, I want to leave the string alone -- even if it has double spaces.

    I have tried a number of variations of @count but none of them work, e.g:

    Set x=abc, 123, def
    • echo %@count[,, %x]
    • echo %@count[^,, %x]
    • echo %@count[",", %x]
    • echo %@count[`,`, %x]
    • echo %@count[',', %x]
    • echo %@count[%@char[44], %x]
    I have tried %@fields[",",%x] However, for Set x=abc it returns 1, meaning there is one field, so I would have to do %@dec[%@fields[",", %x]. That's pretty convoluted just to "count the commas". It seems a built-in @count function should be able to do that.
     
  2. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    I agree. This works but I would hardly call it robust.
    Code:
    v:\> echo %x
    my,dog,has,fleas
    
    v:\> echo %@index["%x",^,,0]
    3
     
  3. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    680
    Likes Received:
    8
    Not a solution using @count, but it works;
    Code:
    function ChrCount=`%@script[vbscript,dim fso:set fso=CreateObject("Scripting.FileSystemObject"):set stdout=fso.GetStandardStream(1):ChrCount = Len(%1) - Len(Replace(%1,",", "")):stdout.WriteLine ChrCount:set fso=Nothing:]`
    Example usage;
    Code:
    echo %@ChrCount["my,dog,has,fleas"]
    3
    Code:
    echo %@ChrCount["The,quick,brown,fox,jumps,over,the,lazy,dog"]
    8
    Joe
     
  4. Rick Reinckens

    Joined:
    Oct 18, 2009
    Messages:
    96
    Likes Received:
    4
    Thanks. But I'm looking for something that works directly, rather than with scripts, writing to a file, etc. @count works with pretty much any other character, so there should be a way to use it with a comma too.

    Since the issue in my case is "Is there at least one comma?" not "How many commas are there?" I was able to use @fields. But there should be a way to use @count -- or at least the Help should specifically say @count won't count commas so use @fields instead, with the comma in quotes, so people won't spend time trying to find the one oddball @count syntax that works.

    In this case, writing to a file wouldn't be practical because the program will be parsing hundreds or even thousands of records and checking several fields to make sure they don't have any commas.
     
  5. Rodolfo

    Joined:
    May 20, 2009
    Messages:
    213
    Likes Received:
    0
    If I understand what You mean, You want to take away commas, but You want to replace them with spaces to keep separators between words, but You do not want double spaces.
    In this case, You might want to try these three lines.
    The first one replaces "a comma followed by a space" with "a space".
    The second one replaces "a space followed by a comma" with "a space".
    So, You take away commas but do not get double spaces.
    The third one replaces each remaining comma with a space.
    Code:
    set x=%@replace[^, , ,%x]
    set x=%@replace[ ^,, ,%x]
    set x=%@replace[^,, ,%x]
    
    For example, there are three possible cases, I believe, and these lines should work in all cases.

    Regards

    Rodolfo Giovanninetti

    Code:
    cls
    
    set x=abc, 123, def
    set x=%@replace[^, , ,%x]
    set x=%@replace[ ^,, ,%x]
    set x=%@replace[^,, ,%x]
    echo %x
    
    set x=abc,123,def
    set x=%@replace[^, , ,%x]
    set x=%@replace[ ^,, ,%x]
    set x=%@replace[^,, ,%x]
    echo %x
    
    set x=abc ,123 ,def
    set x=%@replace[^, , ,%x]
    set x=%@replace[ ^,, ,%x]
    set x=%@replace[^,, ,%x]
    echo %x
    
     
  6. Rodolfo

    Joined:
    May 20, 2009
    Messages:
    213
    Likes Received:
    0
    There might be other cases, for example
    Code:
    set x=abc  ,  123  ,   def
    with more than one space before and/or after the comma.
    If You have to handle also these cases, You might use another variable, for example y.
    You copy x to y.
    After the replacements as in my previous message, You compare x and y.
    If they are different, it means that somewhere a comma has been found, and You can replace double spaces with a single one.

    Regards

    Rodolfo Giovanninetti
     
  7. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,312
    Likes Received:
    39
    Apparently @COUNT can't count commas. Perhaps you could count something else instead...?

    Code:
    set string=This,is,only,a,test.
    set inv=%@char[0xffff]
    echo %@count[%inv,%@replace[^,,%inv,%string]]
    
     
  8. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,972
    Likes Received:
    30
    0xFFFF doesn't work here. Others do, e.g., 160.
     
  9. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,312
    Likes Received:
    39
    I confess I didn't try it with the current version. (It did work on TCC/LE.)

    I picked that value because it's an invalid code point which should never, ever appear in real text; possibly TCC doesn't like it for the same reason.
     
  10. djspits

    Joined:
    Apr 13, 2010
    Messages:
    189
    Likes Received:
    2
    Code:
    %@regex[",",%X]
    will let you know if the are any comma's in your string.
    After that you can use your own @replace[] solution, or use single @rereplace[] for those situations you have an unknown extra number of spaces.

    DJ
     
  11. Rick Reinckens

    Joined:
    Oct 18, 2009
    Messages:
    96
    Likes Received:
    4
    I wound up using something very similar to Rodolfo's code. first I replaced all the commas with {, then replaced <space>{ with space, then {<space> with space, so it winds up needing four lines instead of three.

    Regarding @regex, one problem is that although I have TCC, the person I'm writing this for wouldn't be willing to spend $100 for a copy, so everything has to be TCC/LE compatible.

    But in any case, @count should be able to count commas. Otherwise, exactly what I did happens -- the person keeps trying one variation after another, figuring "Some variation has to work! Now I just have to find it!"
     
  12. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    I can add support to @count for commas, but it will mean that anyone who uses (invalid) space padding around their arguments will find their batch files no longer work. (I.e., "%@count[ a, this is a string ]".) (Yes, a lot of people do that in the name of "readability".)
     
  13. Rick Reinckens

    Joined:
    Oct 18, 2009
    Messages:
    96
    Likes Received:
    4
    Several thoughts:

    1) Tough -- if you really use %@count a lot, just deal with the fact that you can't use space padding with that particular function.

    2) How about having to precede a comma with the escape character if that's what you want to count? I thought that would work and it seems to make the most sense.

    a) I actually don't like the syntax where a comma is treated like just another character. When reading the code it doesn't look like the comma is being treated as a character, it looks like there's one more parameter and some of them are empty.

    I would not interpret echo %@count[,,%myvar] as "count the number of commas in %myvar," I would interpret it as "Oops! I left out the character to search for! The second parameter (before the second comma) probably is the starting position to count."

    On the other hand, I would interpret echo %@count[^,,%myvar] as "count the number of commas".​

    3) Add an optional third parameter for "old" and "new" behavior.

    4) Set it to ignore leading and trailing spaces (or maybe only one leading or trailing space.)

    5) How often do people try to count the occurrences of something in a literal string (as in your example) rather than in a string variable?

    a) Related to that, I can see situations of trying to count occurrences in a combination of a variable plus a literal, e.g., find something in %@count[x,%Qrtr Quarter]​
     
    #13 Rick Reinckens, Feb 27, 2015
    Last edited: Feb 27, 2015
  14. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,312
    Likes Received:
    39
    I like that syntax. But I'm unclear on how escaping works internally. Are the escapes, or flags for escaped chars, still available by the time the @function code gets to see the string?
     
  15. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    As far as the parser is concerned, there isn't any difference between a literal string and a variable. The variable has already been substituted, and all variable function processing is done on literal strings.
     
  16. Rick Reinckens

    Joined:
    Oct 18, 2009
    Messages:
    96
    Likes Received:
    4
    I'm looking at the description in the manual, which says: @COUNT[c,string]: Returns the number of times the character c appears in string.

    I don't see what difference there would be in having it able to count commas. Even if someone adds space padding, that won't change the number of commas. I'm assuming that in your "space padding" example %@count[ a, this is a string ] the function would count the number of times the letter a appears, not the number of times a space appears. As I mentioned, I would definitely not recommend just using [,,<search string>] to search for commas.
     
  17. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    A comma (like a space or switch character) is an argument delimiter in TCC (and CMD). Overloading the meaning makes it more complicated to use, as well as substantially increasing the parser complication, and adds more special case bugs.

    That said, I made a change in 17.0.76 (already uploaded) to support commas as a special case in @COUNT.
     
  18. JohnQSmith

    Joined:
    Jan 19, 2011
    Messages:
    559
    Likes Received:
    7
    Awesome, but what about...
     
  19. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    I don't have any plans to add regular expression support to TCC/LE.
     
  20. JohnQSmith

    Joined:
    Jan 19, 2011
    Messages:
    559
    Likes Received:
    7
    Let me rework the quotes.
     
  21. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    I will probably do a new build of TCC/LE when Windows 10 is released (for version info), and roll up any bug / compatibility fixes as well. Not sure that this merits inclusion.
     

Share This Page