I figured out a way to "get the string". It turned out that information was available on this site. This now works
pattSearch[nb_, patt_] :=
pattSearch[nb, x : patt :> x]
pattSearch[nb_, rule : ((Rule | RuleDelayed)[__])] :=
Block[
{pNb, str, searchStr},
pNb = NotebookGet[nb];
str = First[
FrontEndExecute[FrontEnd`ExportPacket[pNb, "PlainText"]]];
searchStr =
First@StringCases[str, rule];
NotebookFind[nb, searchStr];
SetSelectedNotebook[nb]
]
Example of use
{1, 1};
nb = EvaluationNotebook[];
SelectionMove[nb, Before, Notebook];
pattSearch[nb, Shortest["{1," ~~ ___ ~~ "}"]]
In the example the expression {1,1}
is selected.
Another example, with rules
(*This comment makes sure the line below is not at the start of the \
notebook*)
{1, {1, 1, 1}, 1, 1};
SelectionMove[EvaluationCell[], Before, CellContents];
pattSearch[nb,
"\n" ~~ Shortest[___] ~~
x : Longest["{1," ~~ Except["\n"] ... ~~ "}"] ~~ Shortest[___] ~~
"\n" :> x]
Notes
Remember to use Shortest
, or to handle newlines yourself. We cannot search over multiple lines. I have set it up in terms of rules, so that you can manually search on a line, like in the second example. The second example is ugly in that the pattern does not account for the possibility that the expression is at the start of the notebook.
It would be really nice if we could cycle through the expressions found by StringCases
. Also using First
when we may find no pattern is not nice. Maybe I will try make this nicer.
"\n*"~~patt~~"*\n" :> patt
. A user then always only has to specify a pattern and does not have to keepStringCases
in mind when entering input. Anyway thank you for commenting, such a comment provides a lot of motivation for me :). $\endgroup$