Search code examples
regexclojure

Replace end of string with String/replace and re-pattern - Clojure


I want to remove a substring at the end of a string containing some code. I have a vector a containing the expression "c=c+1" My goal is to remove the expression "c=c+1;" at the end of my expression.

I have used the $ symbol indicating that the substring to replace must be at the end of my code.

Here is the code and the output :

project.core=> (def a [:LangFOR [:before_for "a=0; b="] [:init_var "c=a+1;"] [:loop_condition_expression "c-10;"] [:loop_var_step "c=c+1"] [:statements_OK "a=2*c;"] [:after_for " b+c;"]])
#'project.core/a
project.core=> (prn (str "REGEX debug : " (clojure.string/replace "b=0;c=a+1;a=2*c;c=c+1;c=c+1;a=2*c;c=c+1;" (re-pattern (str "# "(get-in a [4 1]) ";$")) "")))
"REGEX debug : b=0;c=a+1;a=2*c;c=c+1;c=c+1;a=2*c;c=c+1;"
nil

The expected output is :

"REGEX debug : b=0;c=a+1;a=2*c;c=c+1;c=c+1;a=2*c;"

How can I correct my (re-pattern) function?

Thanks.


Solution

  • The string you're using to build the regex pattern has some characters in it that have special meaning in a regular expression. The + in c+1 is interpreted as one or more occurrences of c followed by 1. Java's Pattern class provides a function to escape/quote strings so they can be used literally in regex patterns. You could use it directly, or define a wrapper function:

    (defn re-quote [s]
      (java.util.regex.Pattern/quote s))
    
    (re-quote "c=c+1")
    => "\\Qc=c+1\\E"
    

    This function simply wraps the input string in some special control characters \Q and \E to have the interpreter start and stop the quoting of the contents.

    Now you can use that literal string to build a regex pattern:

    (clojure.string/replace
      "b=0;c=a+1;a=2*c;c=c+1;c=c+1;a=2*c;c=c+1;"
      (re-pattern (str (re-quote "c=c+1;") "$"))
      "")
    => "b=0;c=a+1;a=2*c;c=c+1;c=c+1;a=2*c;"
    

    I removed the leading "# " from the pattern in your example to make this work, because that doesn't appear in the input.