Regex not matching repeated letters
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 i开发者_开发知识库s 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.
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]
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]
).
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.
精彩评论