Question: I am trying to parse a JSON file that use single quotes to get a valid Elasticsearch bulk load JSON format.

What I want to do is replace single quotes with double quotes but I don't want to do it if the single quotes are enclosed by single quotes.

Example:

```
{
    'title': 'Charlie's Angels',
    'review': 'I don't really like this 'movie''
}

```

Should be converted to:

```
{
    "title": "Charlie's Angels",
    "review": "I don't really like this 'movie'"
}

```

So I think I need is a sort of regex that match single all single quotes but those enclosed by single quotes.
Unfortunately I've tried various workarounds but I don't seem to be able to get it right... 

Any suggestions?

Answer: 
Do you want something like this output ?

```
{
    "title": "Charlie's Angels",
    "review": "I don't really like this 'movie'"
  "review": "I don't really like 'this movie'"

"review": "I don't really like 'this' movie"

"review": "'I don't' really like 'this' movie"
}

```

I used `2 regex` to get this output.

```
(?<=\w(?='\w))'  

```

[Demo,,,](https://regex101.com/r/zuUjT4/13) which is used in pre-process for replacing the `'` inside a word to another distinctive strings(`@@@` in this case).

And Replace `'` to `"` in the case of matching this regex.

```
(?m)(?<=\s)(?!'[^']*(?:(?:'[^']*){2})*$)'|'(?=[\.\s\,\:])(?=[^']*(?:(?:'[^']*){2})*$)

```

[Demo](https://regex101.com/r/zuUjT4/16/)

* **Pre-word single quote matching condition**: `a space` exists before the quote and the `number of afterward quotes` must be `odd`.
* **Post-word single quote matching condition**: the number of afterward quotes must be `even` and only `allowed character` exists after the quote.

Python scripts may be like this

```
ss="""{
    'title': 'Charlie's Angels',
    'review': 'I don't really like this 'movie''
'review': 'I don't really like 'this movie''

'review': 'I don't really like 'this' movie'

'review': ''I don't' really like 'this' movie'
}"""

import re
rexpre= re.compile(r"(?<=\w(?='\w))'")
rexquot= re.compile(r"(?m)(?<=\s)(?!'[^']*(?:(?:'[^']*){2})*$)'|'(?=[\.\s\,\:])(?=[^']*(?:(?:'[^']*){2})*$)")
ss=re.sub('@@@',"'",rexquot.sub('"',rexpre.sub("@@@",ss)))
print(ss)

```
The best I was able to do with regex is this:

```
(:?'(.*?)'([:,\s]))

```

It matches only quotes that are followed by a white space, colons or commas, what is ok in your testcase, but may not work always. For more testing, I would need more test data.

You can use this regex like this:

```
data = re.sub("(:?'(.*?)'([:\s]))", lambda m:f'"{m.groups()[1]}"{m.groups()[2]}',data)

```