I tried something similar in the python IDLE but haven't actually tested it within ArcDesktop/field calculator, so if there are any issues, feel free to leave a comment and I'll see what I can do to help, but you should be able to just use an expression along the lines of:
!FieldNameGoesHere!.split("<td>Benchmark: ")[1].split("</td>",1)[0]
Now, that script works for your particular example text above to return the benchmark value. So, in that case what you would want to do is just create a new field (name it benchmark or whatever you want) and then run field calculator on that new field using the above expression (obviously inserting the field name of the field that contains the pop-up-content you provided the sample of above).
Here's the warning I'll give you though: I DON'T KNOW OFF THE TOP OF MY HEAD IF THIS WILL WORK CORRECTLY IF EVERY RECORD DOES NOT HAVE A BENCHMARK VALUE SO USE WITH CAUTION!!! If not every record is going to have a benchmark in it and everything in that exact context as your example text above shows, you may instead want to try something like:
In the pre-script code block
def getBenchmark(a):
try:
return a.split("<td>Benchmark: ")[1].split("</td>",1)[0]
except:
return None
Than in the actual expression field
getBenchmark(!FieldNameGoesHere!)
That would go and populate the calculated field with the benchmark value for all of the records that have one, and leave that field null for all the records that don't have a benchmark value instead of causing an error.
Again, as I said, I hope this works for you and makes sense, but if not, feel free to leave a comment and I can try to help if I am able.
EDIT:
Ok, so apparently, after much frustration and research (I've got a similar situation I'd like to have a functional workflow for, so it's not just for this question), I've realized you can't work with multi-line text values with the python parser in ArcGIS's Calculate Field GP Tool. I don't know all the details of why, but apparently this is a known limitation within the software. Their recommendation is to use an update cursor, which I wouldn't argue with. However, I've never really done that much yet with cursors and I like being able to put things in model builder rather than always having to use a straight python script, so I figured out, more or less, a solution using the VB parser that should do the same thing as the python solution above, except it will handle multi-line text input correctly.
In Pre-Script Code Block:
Dim getValue
If InStr( [PopupInfo] ,"<td>Benchmark: ")>0 Then
x = Right( [PopupInfo] ,Len( [PopupInfo] )-(InStr( [PopupInfo] ,"<td>Benchmark: ")+(Len("<td>Benchmark: ")-1)))
getValue = Left(x,InStr(x,"</td>")-1)
else
getValue = ""
end if
In the expression
getValue
For this way to work, you should just have to create a new field to calc the values into and run this script against it (of course you need to go through the code and replace the field name in the 4 places where it appears in the code block, replace it with your source field's name). The only other difference is that if there is no benchmark value, instead of populating with a null field it will populate with an empty string (not that different but an empty string I think takes up a little bit more storage space). Anyway, I got that to work correctly on my own data set that had a multi-line text with similar content, so... hope it helps.