Search code examples
jsonnet

How to replace part of string BEHIND search criteria in Jsonnet string?


I'm looking for an equivalent to std.strReplace(str, from, to) to replace parts of a string in Jsonnet. I would need from to be more like a "pattern", something like s/key="[^"]*"/key="myNewValue"/g, so actually what I'm looking for would be a regex-search-and-replace.

Edit: Ok this could possibly help me with my specific issue:

local replaceKey(string) = (
  local replaceNext = false;
  std.join('"', [
  if std.endsWith(x, "key=") then
    replaceNext = true;
    x
  else if replaceNext then
    replaceNext = false;
    "myNewValue"
  else
    x
  for x in  std.split(string, '"')
  ])
);

However the "set a new value for previously defined local variable" (replaceNext = true;) won't work.

Not a binary operator: =

Any ideas how to do it?


Solution

  • I have the following solution now:

    local modifyElement(element, newValue) =
      std.join('"', std.mapWithIndex(                                                             
        function(i, str)
          if i == 1 then
            newValue
          else
            str,
        std.split(element, '"')
      ));
    
    local splitSubstring(string, pattern) = (
      local indexes = [0] + std.findSubstr(pattern, string);
      local lenIdx = std.length(indexes);
      local lenStr = std.length(string);
      std.mapWithIndex(
        function(i, strIndex)
          std.substr(string, strIndex, 
            if lenIdx > i+1 then indexes[i+1]-strIndex
            else lenStr-strIndex),
        indexes
      )
    );
    
    local replaceValue(string, searchKey, newValue) = 
      std.join("", std.mapWithIndex(
          function(index, element)
            if index == 0 then
              element
            else
              modifyElement(element, newValue),
        splitSubstring(string, searchKey)));
    
    
    // TESTCASE
    
    local oldExpression = 'rate(kube_pod_container_status_restarts_total{namespace=~"^(ns1|ns2)$",job="expose-kubernetes-metrics"}[10m]) * 60 * 5 > 0';
    {'test': replaceValue(oldExpression, "namespace=~", "^myspaces-.*$")}
    

    However I would be interested in if this could possibly be achieved easier, since this is really insane for such a trivial task.