Sign up ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

(I am sorry for my poor English,I'll try to use a simple sentence to convey me.)

I can use StringCases to get the target to change like this

StringCases["aaabccccc",RegularExpression["(\\w)(\\1+)"] -> "$2"]

{"aa", "cccc"}

But now,I want to use StringReplace to transform the target.How can I use the StringReplace to transform the parenthesized regular expression?Help me please.

Ps:My aim is "axxbcxxxx"


Somebody will assert the regular expression cannot do this,but I can cope the question in Python with regular expression.Like this:

    >>> re.sub(r'(\w)(\1+)', lambda m: m.group(1) + 'x' * len(m.group(2)),'aaabccccc')

    'axxbcxxxx'

But I want to get the solution in Mathematica. (T_T).

share|improve this question
2  
Just use StringReplace["aaabccccc", y : Repeated[x_] :> x <> StringJoin[ConstantArray["x", StringLength@y - 1]]]... – ciao Aug 22 at 8:25

2 Answers 2

up vote 5 down vote accepted

One way to do this using Mathematica's native string patterns is like this:

StringReplace["aaabccccc",
  xs:((x:WordCharacter)..) :> StringPadRight[x, StringLength@xs, "x"] ]

(* "axxbcxxxx" *)

Here is the same replacement expressed using a RegularExpression:

StringReplace["aaabccccc",
  RegularExpression["((\\w)\\2+)"] :> StringPadRight["$2", StringLength@"$1", "x"] ]

(* "axxbcxxxx" *)

It is possible to perform this transformation using a simple regular expression without callbacks -- but only if we reverse the string first (and unreverse the result afterwards):

StringReplace[StringReverse @ "aaabccccc",
  RegularExpression["(\\w)(?=\\1)"] -> "x" ] // StringReverse

(* "axxbcxxxx" *)

The reversal is necessary due to restrictions in the use of look-behind regular expressions:

(* caution: should theoretically work, but doesn't in practice *)
StringReplace["aaabccccc", RegularExpression["(\\w)(?<=\\1\\1)"] -> "x"]

(* RegularExpression::msg25: Lookbehind assertion is not fixed length... *)

The PCRE regular expression engine used by Mathematica neither allows variable-length look-behind assertions nor detects that the look-behind in this case is actually of fixed length. By reversing the string we are able to convert the look-behind assertion into a look-ahead, which is not subject to these limitations.


StringPadRight

StringPadRight was introduced in version 10.1 of Mathematica. In earlier versions, we can define our own:

stringPadRight[s_String, n_Integer, p_String] :=
  PadRight[ToCharacterCode@s, n, ToCharacterCode@p] // FromCharacterCode
share|improve this answer

Using Regexes:

StringReplace["aaabccccc", RegularExpression["(\\w)(\\1+)"] :> 
                                     StringJoin["$1", Array["x" &, StringLength@"$2"]]]
(* "axxbcxxxx" *)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.