Consider the following list:

filenamesSensitivity = {"Sensitivity_MCP_at_LAr-SHiP-ECN3_target_Electrons_Npot=6.e20_Nbg=1._nhits=1._Eemin=0.03.dat", "Sensitivity_MCP_at_SND-SHiP-ECN3_target_Electrons_Npot=6.e20_Nbg=1.dat"};

I want to extract the parameters from these filenames. They have different number of parameters (the first string has two extra parameters in the end), so two different commands are needed:

ParametersSensitivityTemp[i_] := 
   "Sensitivity_MCP_at_" ~~ experiment__ ~~ "_target_" ~~ target__ ~~ 
     "_Npot=" ~~ Npot__ ~~ "_Nbg=" ~~ Nbg__ ~~ ".dat" :> {experiment, 
     target, Npot, Nbg}][[1]]
ParametersSensitivityLArTemp[i_] := 
   "Sensitivity_MCP_at_" ~~ experiment__ ~~ "_target_" ~~ target__ ~~ 
     "_Npot=" ~~ Npot__ ~~ "_Nbg=" ~~ Nbg__ ~~ "_nhits=" ~~ nhits__ ~~
      "_Eemin=" ~~ Eemin__ ~~ ".dat" :> {experiment, target, Npot, 
     Nbg, nhits, Eemin}][[1]]

The first command is expected to extract the parameters from the second string, while the second - from the first string. In the end, I get this:

list1 = Table[
   ParametersSensitivityTemp[i], {i, 1, 
    Length[filenamesSensitivity]}] // TableForm
list2 = Table[
   ParametersSensitivityLArTemp[i], {i, 1, 
    Length[filenamesSensitivity]}] // TableForm

enter image description here

The desired output looks like the two rows - the second row in the first table and the first row in the second table.

So ParametersSensitivityTemp treats 1._nhits=1._Eemin=0.03 from the first string as a single parameter, while ParametersSensitivityLArTemp obviously fails to extract the parameters from the second string.

Could you please tell me how to fix these commands such that each of them would work only with the appropriate strings?

  • 1
    $\begingroup$ Try: StringSplit[filenamesSensitivity, {"-" | "_"}] $\endgroup$ Jul 20, 2023 at 14:07
  • $\begingroup$ @DanielHuber : but then "LAr-SHiP-ECN3" would not be extracted (please see the output of ParametersSensitivityTemp). $\endgroup$ Jul 20, 2023 at 19:51
  • $\begingroup$ If you do not want to split on "-" try: StringSplit[filenamesSensitivity, {"_"}] $\endgroup$ Jul 20, 2023 at 20:00
  • $\begingroup$ @DanielHuber : then it will extract not only the parameters but the rest of the string. $\endgroup$ Jul 20, 2023 at 20:09

2 Answers 2


You could use pattern matching. You can either match on the parameters or on the junk/non-parameters. For example:

NonParamPatterns = {"Sensitivity_MCP_at_", "_target_", ".dat", "_"};
ExtractParams[fileName_String] := StringSplit[fileName, NonParamPatterns]


ExtractParams /@ filenamesSensitivity
(* {{"LAr-SHiP-ECN3", "Electrons", "Npot=6.e20", "Nbg=1.", "nhits=1.", "Eemin=0.03"}, {"SND-SHiP-ECN3", "Electrons", "Npot=6.e20", "Nbg=1"}} *)

Per one of your comments, you want the final 2-3 to be combined into one parameter. That seems awkward to me--it seems clear that "_" is being used as a delimiter. But, if the filename structure is consitent, then that'd be easy to do.

ExtractAndCombineParams[fileName_String] := 
  Flatten[MapAt[StringRiffle, TakeList[ExtractParams[fileName], {2, All}], -1]]


ExtractAndCombineParams /@ filenamesSensitivity
(* {{"LAr-SHiP-ECN3", "Electrons", "Npot=6.e20 Nbg=1. nhits=1. Eemin=0.03"}, {"SND-SHiP-ECN3", "Electrons", "Npot=6.e20 Nbg=1"}} *)

Update Looks like I got the requirement backward. Again, it would be helpful if you just focused on the desired output instead of polluting the expectation with non-desired output. But anyway, let's introduce yet another helper.

ExtractAndStripTags[fileName_String] := 
  StringTrim[ExtractParams[fileName], __ ~~ "="]

And let's update ExtractAndCombineParams to use it (and fix the sequence length while we're at it).

ExtractAndCombineParams[fileName_String] := 
  Flatten[MapAt[StringRiffle, TakeList[ExtractAndStripTags[fileName], {3, All}], -1]]


ExtractAndCombineParams /@ filenamesSensitivity
(* {{"LAr-SHiP-ECN3", "Electrons", "6.e20", "1. 1. 0.03"}, {"SND-SHiP-ECN3", "Electrons", "6.e20", "1"}} *)

You don't need multiple functions.

ExtractParams[fileName_String] := 
  Select[StringSplit[StringTrim[fileName, "." ~~ WordCharacter ..], "_"], StringContainsQ["="]]


ExtractParams /@ filenamesSensitivity
(* {{"Npot=6.e20", "Nbg=1.", "nhits=1.", "Eemin=0.03"}, {"Npot=6.e20", "Nbg=1"}} *)

But you might want to do some further processing so you can use those parameters as Wolfram Language expressions, so here's an alternate:

ExtractParamsAsRules[fileName_String] := 
    Rule @@@ 
          StringSplit[StringTrim[fileName, "." ~~ WordCharacter..], "_"], 
    {All, -1}]


ExtractParamsAsRules /@ filenamesSensitivity
(* {{"Npot" -> 6.*^20, "Nbg" -> 1., "nhits" -> 1., "Eemin" -> 0.03}, {"Npot" -> 6.*^20, "Nbg" -> 1}} *)

Note: I've obviously made some assumptions about the format of the filename and the interpretation of the parameters--adjust as necessary.

  • $\begingroup$ Thanks! But these commands do not extract "Electrons" and "LAr-SHiP-ECN3", only numbers (please see the output of ParametersSensitivityTemp). $\endgroup$ Jul 20, 2023 at 19:48
  • $\begingroup$ Oh, I thought the "=" assignments were the parameters. But anyway, if you looked at my code, it's pretty easy to see how to include the others. $\endgroup$
    – lericr
    Jul 20, 2023 at 20:22
  • $\begingroup$ Before I edit my answer, you should update your question to specify exactly what you want the output to be, instead of telling us what you don't want the output to be. $\endgroup$
    – lericr
    Jul 20, 2023 at 20:24
  • $\begingroup$ I have edited the question. $\endgroup$ Jul 20, 2023 at 20:32
  • $\begingroup$ Do the filenames always have this same strucutre? $\endgroup$
    – lericr
    Jul 20, 2023 at 20:39

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.