3
$\begingroup$

Consider an .html file. Among the code, it contains there are strings

    <td rowspan=1>run_36</td> 
    <td rowspan=1><center> numu nn <br> 12.5 x 0.9391  GeV </center></td>
    
    <td rowspan=1> <a href="./Events/run_36/run_36_tag_1_banner.txt">tag_1</a></td>
    
    <td rowspan=1><center><a href="./HTML/run_36/results.html"> 1.324e-06 <font face=symbol>&#177;</font> 2.8e-09 </a>  </center></td>

I am interested in the numbers 12.5 and 1.324e-06, which are placed before

<td rowspan=1><center> numu nn <be>

and

<a href="./HTML/run_XX/results.html">

where XX are some arbitrary numbers.

Could you please tell me how to extract the table

tab = {{12.5, 1.324*10^-6},...}

from this file?

$\endgroup$
2
  • $\begingroup$ Some things to get you started. data = Import[pathToFile, "Data"] will get the table (hopefully). It'll be a normal Mathematica list of lists, so you can do whatever you want with it (like apply TableForm to see it formatted nicely). You can also try html = Import[pathToFile, "XMLObject"] which will give you an XMLObject that you can traverse/inspect/filter/whatever. Either method should allow you to "extract the table" or any part of it. But are you going to need to parse the number-looking-strings into actual structures that Mathematica will interpret as numbers? $\endgroup$
    – lericr
    Aug 4, 2022 at 21:36
  • $\begingroup$ @lelicr : yes, I need to use them later as numbers. $\endgroup$ Aug 4, 2022 at 21:41

2 Answers 2

3
$\begingroup$

To read the html file you may use:

str = Import["d:/tmp/test.html"]

This will return a string. Then you can user "StringCases" to pick out the numbers you want. You must identify in some way the numbers you are looking for. For the first cases this can be done by: "the number before the x":

StringCases[str, x : NumberString ~~ " x" :> x]

(* {"12.5"} *)

The second case is more difficult because it is in an exponential notation:

StringCases[str, 
 x : (NumberString ~~ "e" ~~ "-" ~~ NumberString) ~~ " \[PlusMinus]" :>
   x]

(* "1.324e-06"} *)
$\endgroup$
2
$\begingroup$

Here's an approach. Start by defining functions to interpret the particular strings you're interested in. Looking at the data, it seems like you're interested in the "Collider" column and the "Cross section" column.

InterpretCollider[collider_String] := SemanticInterpretation[StringDrop[collider, 8]];
InterpretCrossSection[xsection_String] := SemanticInterpretation[StringSplit[xsection, "\[PlusMinus]"][[1]]]

Couple of assumptions here. I'm assuming that the Collider data always has the same prefix (and it's 8 characters). And I'm assuming that you're okay with Quantities. I'm also assuming that \[PlusMinus] is the right character to split on for CrossSection. Be prepared to make adjustments if those turn out to be wrong.

Now we need to get the data.

data = Import[pathToFile, "Data"]

That worked for me if I downloaded the file from your link (so pathToFile was a local filepath. Not sure what mechanism you're wanting to use. Be prepared to adjust as necessary.

Now that we have the table, we can manipulate it and apply functions to it. If I take your structural requirement literally, we need to ditch the column headers and keep only the 2nd and 4th columns. Then we can map our interpreter functions appropriately.

Start by noting this

data[[2 ;;, {2, 4}]]

which gets the two columns you want. Now, there's probably a fancy way to thread our functions nicely, but here's a simplistic way:

MapAt[
  InterpretCollider, 
  MapAt[
    InterpretCrossSection, 
    data[[2 ;;, {2, 4}]], 
    {All, 2}], 
  {All, 1}]

Since we're using SemanticInterpretation, this actually takes a few seconds. You could do your own string parsing if timing is an issue.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.