-2
$\begingroup$

I want to make some cutoff for some string in a text file. It has a character like this, "gk={....}". For example, there are some strings as follows,

   "gk={cdfaad efe,csfa def,fasdf,cdf sdf,dfsd,1234,34}"

   "gk={abcde}"

   "gk={tk1,tekdfs,sd}"

If gk list has more than three elements, we should remove some elements behind in gk list so that gk only has three elements and the third element should make some change. After some kind of replacement, the result should be

   "gk={cdfaad efe,csfa def,fasdf xxxxx}"

   "gk={abcde}"

   "gk={tk1,tekdfs,sd}"

How to make this kind of replacement in a text file using mathematica ?

$\endgroup$
  • 1
    $\begingroup$ This question is really too broad. Rather than asking about a specific Mathematica issue, you are asking that someone write a complete program for you. On the whole such requests are not well received. $\endgroup$ – m_goldberg Sep 13 '16 at 11:43
  • $\begingroup$ I don't think this is broad. Using StringReplace[ ], I just want to know how to construct a simple replacement rule. $\endgroup$ – Orders Sep 13 '16 at 12:04
  • 2
    $\begingroup$ Then you shouldn't be mentioning anything about text files. Your question as now posed appears to ask not only about string replacement but how to read in the data from a file, modify the data, and write it back out again. $\endgroup$ – m_goldberg Sep 13 '16 at 12:09
2
$\begingroup$

String patterns

Code.

processString[str_String] := StringReplace[str,
 StartOfString ~~
 assign : (LetterCharacter .. ~~ "={") ~~
 chars : Repeated[(LetterCharacter | DigitCharacter | WhitespaceCharacter) .. ~~ ",", {3}] ~~
 ((LetterCharacter | DigitCharacter | WhitespaceCharacter) .. ~~ ",") ... ~~
 (LetterCharacter | DigitCharacter | WhitespaceCharacter) .. ~~ "}" ~~
 EndOfString 
 :> assign <> StringDrop[chars, -1] <> " xxxxx" <> "}"
]

Usage.

processString[s1]
(* "gk={cdfaad efe,csfa def,fasdf xxxxx}" *)

processString[s2]
(* "gk={abcde}" *)

processString[s3]
(* "gk={tk1,tekdfs,sd}" *)

Comments.

a) StartOfString and EndOfString ensures that the pattern to match applies to the whole string, and not to some of its parts.

b) Lines 5 and 6 in the code above are needed to make sure the whole string has the correct structure.

c) In case "xxxxx" depends on the removed parts of the initial string, you can use named patterns for lines 5 and 6, and then process those.

Regular expression

Code.

processStringRegex[str_String] := StringReplace[str,
  RegularExpression["^([[:alpha:]]+={)((([[:alnum:]]|[[:space:]])+?,){3})((([[:alnum:]]|[[:space:]])+,)*)([[:alnum:]]|[[:space:]])+}$"]
  :> "$1" <> StringDrop["$2", -1] <> " xxxxx" <> "}"
]

Usage.

processStringRegex[s1]
(* "gk={cdfaad efe,csfa def,fasdf xxxxx}" *)

processStringRegex[s2]
(* "gk={abcde}" *)

processStringRegex[s3]
(* "gk={tk1,tekdfs,sd}" *)

Comments.

a) ^ and $ ensures that the regular expression applies to the whole string, and not to some of its parts.

b) "$1" corresponds to the substring matched by the first parenthesized regular expression, i.e. by [[:alpha:]]+={. $2 corresponds to the second one, i.e. (([[:alnum:]]|[[:space:]])+?,){3}.

$\endgroup$
1
$\begingroup$
s1 = "gk={cdfaad efe,csfa def,fasdf,cdf sdf,dfsd,1234,34}";
s2 = "gk={abcde}";
s3 = "gk={tk1,tekdfs,sd}";

f[s_String] := Module[{se = ToExpression[s]},
  out = First@StringSplit[s, "{"] <> 
    ToString@
     If[Length@se > 3, 
      Flatten@Join@{se[[1 ;; 2]], 
         ToExpression[ToString@se[[3]] <> " something"]}, se

f[s1]

"gk={cdfaad efe, csfa def, fasdf something}"

f[s2]

"gk={abcde}"

f[s3]

"gk={tk1, tekdfs, sd}"

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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