You should consider using a proper HTML parser for that job.
If that's for a one time use though, you could try using a regex like this:
<tr>[^<]*<td[^>]*>[^<]*</td>[^<]*<td[^>]*>([^<]+)
EDIT: And here's an ideone demo.
Question
I have a html page with source code as below. My requirement is to search for given word only in column with heading "Ship Name". I would like to know which Regex would help me to only extract this particular column's data.
I have used following two Regex to extract table headers and rows:
table headers = @"<th[^>]*?>(?<Value>.*?)</th>"
by this regex I can find the column Ship Name
table rows = @"<td>(.*?)</td>"
by this regex I can get every column of every row
but my need is just to find 2nd column of every row. Please help if there exists any such regex with which i can do this or any other method by which i can get my job done. Please Help me
Html Page source code is:
<link href="http://www.mhpa.co.uk/reports.css" rel="STYLESHEET" type="text/css" CHARSET="ISO-8859-1">
<table cellpadding=2 cellspacing=0 border=0 width=100%>
<tbody>
<tr>
<td align=right><b>11/09/2013 at 09:48</b></td>
</tr>
</tbody>
</table>
<center>
<table border="1" bordercolor="silver" cellpadding="2" cellspacing="0" width="100%">
<thead>
<tr>
<th width=100>ETA</th>
<th width=100>Ship Name</th>
<th width=80>From port</th>
<th width=80>To berth</th>
<th width=130>Agent</th>
</tr>
</thead>
<tbody>
<tr><td>11/09/2013 at 09:00 </td>
<td>SONANGOL KALANDULA </td>
<td>Cabinda </td>
<td>Valero 6 </td>
<td>Graypen </td>
</tr>
<tr>
<td>11/09/2013 at 11:45 </td>
<td>ISLE OF INISHMORE </td>
<td>Rosslare </td>
<td>PDFT </td>
<td>Irish Ferries </td>
</tr>
<tr>
<td>11/09/2013 at 12:00 </td>
<td>BRO DEVELOPER </td>
<td>Avonmouth </td>
<td>Valero 8 </td>
<td>GAC </td>
</tr>
<tr>
<td>11/09/2013 at 14:00 </td>
<td>WELSH PIPER </td>
<td>Sea </td>
<td>POP No 1 </td>
<td>Tarmac Marine Dredging Ltd </td>
</tr>
<tr>
<td>11/09/2013 at 22:00 </td>
<td>PATRICIA </td>
<td>Le Havre </td>
<td>Murco 1 </td>
<td>GAC </td>
</tr>
<tr>
<td>12/09/2013 at 05:00 </td>
<td>BRO DESIGNER </td>
<td>Plymouth </td>
<td>Murco 2 </td>
<td>Graypen </td>
</tr>
<tr>
<td>12/09/2013 at 06:00 </td>
<td>BASTOGNE </td>
<td>Mongstad </td>
<td>Valero 3 </td>
<td>Denholm Wilhelmsen Ltd </td>
</tr>
<tr>
<td>12/09/2013 at 06:00 </td>
<td>MINERVA GRACE </td>
<td>Ras Lanuf </td>
<td>Valero 1 </td>
<td>Graypen </td>
</tr>
<tr>
<td>12/09/2013 at 06:00 </td>
<td>LEANDER </td>
<td>Dublin </td>
<td>Murco 2 </td>
<td>Graypen </td>
</tr>
<tr>
<td>12/09/2013 at 07:00 </td>
<td>THUN GLOBE </td>
<td>Cardiff </td>
<td>Valero 7 </td>
<td>GAC </td>
</tr>
<tr>
<td>13/09/2013 at 06:00 </td>
<td>THUN GENIUS </td>
<td>Dublin </td>
<td>Valero </td>
<td>GAC </td>
</tr>
<tr>
<td>13/09/2013 at 11:00 </td>
<td>CAP LEON </td>
<td>Arzew </td>
<td>Valero 6 </td>
<td>Graypen </td>
</tr>
<tr>
<td>13/09/2013 at 19:00 </td>
<td>STOLT TEAL </td>
<td>TBA </td>
<td>Valero 1 </td>
<td>Cory Bros </td>
</tr>
<tr>
<td>14/09/2013 at 16:00 </td>
<td>B GAS LANRICK </td>
<td>Antwerp </td>
<td>Murco 3 </td>
<td>S5 Agency World </td>
</tr>
<tr>
<td>15/09/2013 at 09:00 </td>
<td>BAYAMO </td>
<td>TBA </td>
<td>Valero </td>
<td>Graypen </td>
</tr>
<tr>
<td>15/09/2013 at 09:00 </td>
<td>AMADEA </td>
<td>Cork </td>
<td>Milford Shelf </td>
<td>Inchcape Shipping Services </td>
</tr>
<tr>
<td>15/09/2013 at 12:00 </td>
<td>ARRAN </td>
<td>Dublin </td>
<td>Valero </td>
<td>Graypen </td>
</tr>
<tr>
<td>16/09/2013 at 01:00 </td>
<td>EKFJORD </td>
<td>Gothenburg </td>
<td>Murco 1 </td>
<td>Cory Bros </td>
</tr>
<tr>
<td>16/09/2013 at 21:30 </td>
<td>MOZAH </td>
<td>Ras Laffan </td>
<td>South Hook No 1 </td>
<td>S5 Agency World </td>
</tr>
<tr>
<td>17/09/2013 at 07:00 </td>
<td>STRIDE </td>
<td>Murmansk </td>
<td>Valero 6 </td>
<td>Graypen </td>
</tr>
</tbody>
</table>
</center>
As in above source code of html, I only want to search the 2nd column of every row for example only BAYAMO
, STRIDE
etc should be searched
Solution
You should consider using a proper HTML parser for that job.
If that's for a one time use though, you could try using a regex like this:
<tr>[^<]*<td[^>]*>[^<]*</td>[^<]*<td[^>]*>([^<]+)
EDIT: And here's an ideone demo.
OTHER TIPS
A simple start:
<tr>.*?<td>.*?</td>.*?<td>(.*?)</td>
But that doesn't quite work, what if you have single-column rows? It will keep going until you get to the next row and match the first column there.
For this, we need something more complicated:
<tr>(?:.(?!<tr>))*?<td>.*?</td>(?:.(?!<tr>))*?<td>(.*?)</td>
It obviously won't work so nicely for nested tables and things, but this is the danger of trying to parse HTML with regex. For more on this, and just in general, I suggest you read this.
Test.
Explanation:
(?:...)
is a non-capturing group, it doesn't change the match, just prevents it from being recorded in a group.
(?!...)
is negative lookahead, matching if the following characters don't match some pattern.