3
$\begingroup$

For example I have a dot file that describe a decision tree or binary tree

enter image description here

In the file, the color of node is always gold, so I try to change it according the number in "cep_s\*_\*", in this image it's 91.

enter image description here

First I use StringMatchQ to check if No.136 line match a pattern.

txt = Import["https://wolfr.am/zp54P15j", "Lines"];
p = StartOfLine ~~ Whitespace ~~ "\"cep_s" ~~ DigitCharacter ~~ "_" ~~
    DigitCharacter .. ~~ "*fillcolor=" ~~ "gold" ~~ "];";
StringMatchQ[txt[[136]], p]
(*True*)

Then I can use this rule to map all the node to change their color according to their number in "cep_s\*_\*".

Just for simple, here use three colors.

txt = Import["https://wolfr.am/zp54P15j", "String"];
colors = {"black", "yellow", "red"};
txtNew = StringReplace[txt, 
   a : (StartOfLine ~~ Whitespace ~~ "\"cep_s" ~~ DigitCharacter ~~ 
        "_") ~~ b : DigitCharacter .. ~~ c : "*fillcolor=" ~~ 
     d : "gold" ~~ e : "];" :> 
    a <> b <> c <> colors[[Mod[ToExpression[b], 3] + 1]] <> e];
txtNew == txt
(*True*)

txtNew is equal txt, nothing change. I don't know what is wrong. Thank you for your reply!

PS: Using this code in terminal can visualize(using graphviz) the decision tree like the top image

dot -Tpng test.dot -o test.png

dot -Tpdf test.dot -o test.pdf

$\endgroup$
  • $\begingroup$ ToExpression[b] %3 + 1 should be Mod[ToExpression[b], 3] + 1? $\endgroup$ – Rohit Namjoshi Nov 26 '18 at 5:12
  • $\begingroup$ yes, i used python grammar... 😃thanks fot point out $\endgroup$ – partida Nov 26 '18 at 5:20
1
$\begingroup$

Use c : Shortest[___ ~~ "fillcolor="] instead of c : "*fillcolor=":

txt = Import["https://wolfr.am/zp54P15j", "String"];
colors = {"black", "yellow", "red"};
txtNew = StringReplace[txt, 
   a : (StartOfLine ~~ Whitespace ~~ "\"cep_s" ~~ DigitCharacter ~~  "_") ~~ 
   b : DigitCharacter .. ~~ 
   c : Shortest[___ ~~ "fillcolor="] ~~ 
   d : "gold" ~~ e : "];" :> a <> b <> c <> colors[[Mod[ToExpression[b], 3] + 1]] <> e];

StringCases[txtNew, StartOfLine ~~ Whitespace ~~ "\"cep_s" ~~ DigitCharacter ~~
      "_" ~~ DigitCharacter .. ~~ Shortest[___] ~~ "];"] //  Short[#, 5] &

enter image description here

Note: StringMatchQ allows abbreviated string patterns containing "*" but in StringReplace, StringCases, StringPosition etc "*" in the pattern "*fillcolor=" is taken literally. Using a simpler example:

StringMatchQ["abc  def", "*def"]

True

StringReplace["abc  def", "*def" :> "XX" <> "1"]

"abc def"

StringReplace["abc  def", ___ ~~ "def" :> "XX" <> "1"]

"XX1"

StringCases["abc  def", "*def"]

{}

StringCases["abc  def", ___ ~~ "def"]

{"abc def"}

$\endgroup$
  • $\begingroup$ like a tutorial. This problem puzzle me a half day. Thank you give such a detailed answer and figure out the difference between these String* function $\endgroup$ – partida Nov 26 '18 at 14:45

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.