tags:

views:

81

answers:

4
myString = "THIS THING CAN KISS MY BUTT. HERE ARE MORE SSS";
myNewString = reReplace(myString, "[^0-9|^S{2}]", "|", "All");

myNewString is "|||S||||||||||||SS||||||||||||||||||||||||SSS"

What I want is "||||||||||||||||SS|||||||||||||||||||||||||||" which is what I thought ^S{2} would do (exclude exactly 2 S). Why is it matching any S? Can someone tell me how to fix it? TIA.

actual goal I'm trying to validate a list of values. Acceptable values would be 6 digit numbers or 5 digit numbers proceeded by SS so 123456,SS12345 is a valid list. what i'm trying to do is make everything that isn't SS or a number into a new delimiter because i have no control over the input. for example 123456 AND SS12345 should be changed to 123456|||||SS12345. after changing the | delimiter to , the result is 123456,SS12345. If a user were to enter 123456 PLUS SS12345 ends up with 123456||||S|SS12345 which = 123456,S,SS12345 which is invalid and the user gets an error, but it should be valid if it didn't match the single S.

+8  A: 

The [^0-9|^S{2}] actually means:

[^     # any character except
  0-9  #  0 to 9
  |    #  a vertical bar
  ^    #  a caret 
  S    #  an S            <-----
  {    #  an open brace
  2    #  a 2, and
  }    #  a close brace
]

Therefore it is not matching any S.

Since CodeFusion doesn't support lookbehind or having a callback in the replacement, I don't think this can be solved simply with just REReplace.

I don't know CF but I'll try something like:

resultString = "";
sCount = 0
for character in myString + "$":
  if character == 'S':
    sCount += 1
  else:
    if sCount == 2:
      resultString += "SS"
    else:
      resultString += "|" * sCount
    sCount = 0
    if isdigit(character):
      resultString += character
    else:
      resultString += "|"
resultString = resultString[:-1]
KennyTM
hmm, ok, thanks. any suggestions on the solution?
Travis
ColdFusion, and I didn't tag it CF in purpose. Just because it's in reReplace... That's like asking CF for help with a broken oracle query just because it's in cfquery tags when it's an oracle question.
Travis
@Travis: What's your language then. You see, it is important to know what the regex engine is using. It accepts the solution very much.
KennyTM
it is coldfusion, which I believe uses the JVM engine. I could be wrong though, I don't mess with regex too often.
Travis
@Travis: [According to Adobe](http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec0a38f-7ff3.html), it is not. And put back the `[coldfusion]` tag in.
KennyTM
+2  A: 

You're using a negative character class with [^....], any character NOT in 0-9|^S{2} will be replaced so 0-9, ^,{ & } will also survive. Negative matching of actual strings instead of characters would be quite hard. Simply only replacing 'SS{2}' would be: (?<!S)SS(?!S), anything BUT 'SS' is hardly doable. My best effort would be (?<=SS)S|S(?=SS)|(?<=S)S(?=S)|(?<!S)S(?!S)|[^S0-9], but I cannot guarantee it.

Wrikken
Wrikken
A: 

Travis,

Could you please clarify your question? First you say:

What I want is "||||||||||||||||SS|||||||||||||||||||||||||||"

But then you say:

exclude exactly 2 S

Did you mean "exclude" or include only two "S"? Does that mean that "S", "SSS, "SSSS", and so on, should be not be selected?

Just to be clear, is it okay to have an hypothetical answer like "||||||||SS|||||||SS|||", or only the first one should be selected?

luiscolorado
+2  A: 

Am I reading this correctly in that you want to replace everything except exactly two consecutive S characters?

Is this restricted to a single replace call or can you run it through multiple regex operations? If multiple operations are allowed, it might be easier to run the string through one regex that matches against S{3,} (to pick up instances of three or more S characters) and then through a second one that uses ([^S])S([^S]) (to pick up single S characters). A third run could match against the rest of your rule ([^0-9]).

bta
I was hoping to do it in one, but I can do multiple. It seems excluding a string should be as easy as !matching.
Travis