4
$\begingroup$

(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).

$\endgroup$
1
  • 2
    $\begingroup$ Just use StringReplace["aaabccccc", y : Repeated[x_] :> x <> StringJoin[ConstantArray["x", StringLength@y - 1]]]... $\endgroup$
    – ciao
    Aug 22, 2015 at 8:25

2 Answers 2

6
$\begingroup$

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
$\endgroup$
5
$\begingroup$

Using Regexes:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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