pythonjsonstringreplacerawstring

Python: Error while reading and replacing String(with special characters) from file


a.json file:

{
  "a": "b",
  "key": "graph: \"color\" = 'black' AND \"api\" = 'demo-application-v1' nodes",
  "c": "d"
}

following code I tried:

string_to_be_replace = "abcd"
string_to = "graph: \"color\" = 'black' AND \"api\" = 'demo-application-v1' nodes"
string_to_be_identified = "\"color\" = \'black\' AND \"api\" = \'demo-application-v1\'"
string_to_be_identified1 = '"color" = \'black\' AND "api" = \'demo-application-v1\''

print string_to_be_identified
print string_to_be_identified1
print string_to.replace(string_to_be_identified1,string_to_be_replace)
print string.replace(string_to, string_to_be_identified,string_to_be_replace)

output:

"color" = 'black' AND "api" = 'demo-application-v1'
"color" = 'black' AND "api" = 'demo-application-v1'
graph: abcd nodes
graph: abcd nodes

This is working fine and replacing string as expected but

it is not when I tried the following approaches

Approach 1:

  1. Open file in a read mode,

  2. get line by line and replace string

with open(path + '/a.json', 'r') as file:
    read_lines = file.readlines()
    for line in read_lines:
        print line.replace(string_to_be_identified,string_to_be_replace)
file.close()

output:

{
  "a": "b",
  "key": "graph: \"color\" = 'black' AND \"api\" ='demo-application-v1' node",
  "c": "d"
}

Approach 2:

  1. Open file in reading mode,

  2. Since the file a.json has JSON data, get JSON file loaded, convert JSON object to JSON-string and then replace it.

Code:

 with open(path + '/a.json', 'r') as file:
    loadedJson = json.load(file)
    print "z: " + str(loadedJson).replace(string_to_be_identified, string_to_be_replace)
file.close()

output:

z: {u'a': u'b', u'c': u'd', u'key': u'graph: "color" = 'black' AND "api" = 'demo-application-v1' node'}

Approach 3:

I assume Unicode character in JSON string might be creating a problem so converted Unicode string to normal string and then tried to replace string

code:

def byteify(input):
    if isinstance(input, dict):
        return {byteify(key): byteify(value)
                for key, value in input.iteritems()}
    elif isinstance(input, list):
        return [byteify(element) for element in input]
    elif isinstance(input, unicode):
        return input.encode('utf-8')
    else:
        return input

with open(path + '/a.json', 'r') as file:
    loadedJson = json.load(file)
    js = byteify(loadedJson)
    print "a: " + str(js).replace(string_to_be_identified, string_to_be_replace)

output:

a: {'a': 'b', 'c': 'd', 'key': 'graph: "color" = 'black' AND "api" = 'demo-application-v1' node'}


Solution

  • While I certainly do not recommend any sort of context-unaware search & replace in a hierarchical structure like JSON, your main issue is that the string you're searching for in your JSON file has escaped quotations (literal \ characters) so you have to account for those as well if you want to do plain text search. You can use either raw strings or add the backslashes yourself, something like:

    str_search = r"graph: \"color\" = 'black' AND \"api\" = 'demo-application-v1'"
    # or, if you prefer to manually write down the string instead of declaring it 'raw':
    # str_search = "graph: \\\"color\\\" = 'black' AND \\\"api\\\" = 'demo-application-v1'"
    str_replace = "abcd"
    
    with open("/path/to/your.json", "r") as f:
        for line in f:
            print(line.replace(str_search, str_replace))
    

    Which, for your JSON, will yield:

    {
    
      "a": "b",
    
      "key": "abcd nodes",
    
      "c": "d"
    
    }

    (Extra new lines added by print).