Question: I have a string given below.

```
AppCodename: Mozilla<br>Appversion: 5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/41.0.2272.76 Chrome/41.0.2272.76 Safari/537.36<br>

```

I want to extract `Mozilla` from the above string. I use the following python program.

```py
import re
import json

with open('data.txt','rb') as f:                                                                                                                                                               
    data = json.load(f)
    message = data['Message']
    appcodename = re.sub('.+AppCodename: ([^<br>])(.*)',r'\1',message,1)
    print('appcode name {}'.format(appcodename))

```

The output that I get is 

```
appcode name M

```

What is wrong with my regex.

Answer: 
The problem with your regex is twofold:

1. You are using a negated class `[^<br>]` which matches any character except `<`, `b`, `r` and `>` (their order is irrelevant). This does not cause any problem with this particular case, but it is not advised to use a negated class to prevent matches for specific sequence of characters.
2. You want `([^<br>])` which can match only 1 character to match `Mozilla` which is several characters long.

Quick & dirty fix:

```
appcodename = re.sub('.*AppCodename: ([^<br>]+)(.*)',r'\1',message,1)

```

`.*` allows matches if the string begins with `AppCodename` and `([^<br>]+)` allows matching of more than one character.

As I mentioned above, the negated character class is not advised. Thus, this is the next step to make the above better:

```
appcodename = re.sub(r'.*AppCodename: ((?:(?!<br>).)+).*',r'\1',message,1)

```

`(?:(?!<br>).)+` is a bit slow (this uses a negative lookahead `(?! ... )`), but it will match any number of characters as long as `<br>` is not within those characters. It is basically checking each character, and each time, it makes sure there is no `<br>` at that character before attempting to match it. Next, rawing a regex string is always advised to avoid unexpected behaviours.

Finally, replacing before and after is not very practical; matching would make things much simpler:

```
appcodename = re.search(r'AppCodename: ((?:(?!<br>).)+)', message).group(1)

```

At that point, you might use something like that instead, which does not use the negative lookahead and much simpler to read I believe:

```
appcodename = re.search(r'AppCodename: (.+?)<br>', message).group(1)

```
Use the following `regex`:

```
# match anything after AppCodename: and before <br>.
'.*AppCodename: ([\w]+?)<br>(.*)'

```

Output:

```
appcode name Mozilla

```