Question: I want to get a string between two patterns. The pattern is the first environment `<p> </p>` in an html file.

```
<p>Sorcery, 
          R (1)
          </p>
        <p class="ctext"><b>As an additional cost to cast Goblin Grenade, sacrifice a Goblin.<br><br>Goblin Grenade deals 5 damage to target creature or player.</b></p>

      <p><i>Don't underestimate the aerodynamic qualities of the common goblin.</i></p>
      <p>Illus. Kev Walker</p>

```

That environment is the first of the file so I discard everything matched until the `<p>` and I want to delete everything after the `</p>`.

```
name="goblin grenade"
wget -O- http://magiccards.info/query?q="$name" | grep -oP '<p>\K[^<]+'

```

I don't know why it doesn't work properly. I get

```
Sorcery, 
Illus. Kev Walker

```

Answer: 
Don't parse HTML with regex, instead, use a proper HTML parser.

### theory :

According to the compiling theory, HTML can't be parsed using regex based on [finite state machine](http://en.wikipedia.org/wiki/Finite-state_machine). Due to hierarchical construction of HTML you need to use a [pushdown automaton](http://en.wikipedia.org/wiki/Pushdown_automaton) and manipulate [LALR](http://en.wikipedia.org/wiki/LR_parser) grammar using tool like [YACC](http://en.wikipedia.org/wiki/Yacc).

### realLife©®™ everyday tool :

instead, you should using a correct tool for a correct job.

...and it's a job for [xmllint](/questions/tagged/xmllint "show questions tagged 'xmllint'") :

by *string matching* :

```
string="Sorcery"
xmllint --html --xpath "//p[contains(text(), '$string')]/text()" file_or_URL

```

by the Nth `<p>` node where N is 1 here :

```
xmllint --html --xpath "//p[1]/text()" file_or_URL

```

Check <https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags>
Disclaimer:

@sputnick answer is clearly the right way to go. (I love xmllint and i use it for several XML/HTML tasks; thank you for teaching me about xpath option!!)

Nevertheless other less robust techniques can also be useful in
disposable scripting...

Getting the first paragraph with regex (in Perl)

```
perl -n0e 'm!<p.*?>(.*?)</p>!s   and print $1'

```

or if you want to remove '`\n`'

```
perl -n0e 'm!<p.*?>(.*?)</p>!s   and print $1 =~ s/\n//gr'

```