A Find/Replace "Step" for Custom Actions (with RegEx)


#1

There is a search “action” that allows for regex find and replace, but this is not easily turned into a custom workflow. Right now the only way I can find to build a custom workflow that does a simple find/replace action is to write a JavaScript that does this. For a non-programmer (like myself) this is a huge wall to climb, especially when almost every other aspect of using the app is quite simple and accessible. I tried copying and modifying existing scripts but I wasted an hour getting nothing but incomprehensible error messages! I am quite proficient at using RegEx functions in search and replace and have managed to create workflows using these in Workflow, Editorial, etc… but none of these require me to learn how to program in JavaScript to accomplish this. I hope this can be made a little easier!


RegEx find/replace template?
#2

Is the new find and replace feature serving this need? Is it just that you want to be able to have saved replace function that this does not work for?


#3

I think he wants a regexp find/replace action, so that he can perform automated (predefined) replacements as part of other actions. Like the Text Factories feature in BBEdit on macOS.


#4

I don’t see any way to use this to save searches for re-use or to incorporate them into larger saved workflows alongside other actions. Am I missing something? The documentation doesn’t seem to indicate such features exist, and this search feature is not accessible from within the custom action menu.


#5

Should be readily possible, via some JavaScript and the Prompt class. I might look into making such an action if I have some time this weekend, or others can.

In your own attempts to deal with regexps in JavaScript, you were probably running into the issue of escaping special characters in JavaScript strings for regular expressions. You can use \n and \r as is, but you’ll need to double-escape (i.e. double-backslash) most of the other character classes, e.g. \\s for whitespace, \\d for digits, etc. Fairly likely that was the problem you were encountering. Note that that’s just if you’re constructing regular expressions in JavaScript using strings, not when using Drafts’ normal Search functionality.


#6

The issue is that I don’t understand JavaScript at all and couldn’t even do a simple search and replace command… :frowning:


#7

Am I missing something? Is it possible to save search patterns already? I didn’t see this in the documentation. I don’t even see a search history that lets you call up previous searches like I can do in BBEdit? Confused by @agiletortoise’s reply…


#8

There are no saved searches at the moment, no. @agiletortoise just thought you meant a search/replace function in the app, rather than the ability to perform such operations as part of an action. Hence the confusion.


#9

Here’s a simple scripted example action that does a global regex replace. It could easily be modified by changing the regex expression and replacement values at the top of the script.

I’ve got saving a find history on the list to add at some point. The find view was very much modeled after BBEdit’s, so adding that history was something I always wanted to do, just haven’t gotten to it.


#10

This will be helpful down the road. How about a simple script for a non-regex find and replace? I have a textsoap scrub that I do on my mac that involves running several find and replaces at once, and it would be great to be able to run directly such a quick job within Drafts.


#11

This same example will work with plain text searches. Just define the values at the top as strings, like:

const findRegex = "find this string";
const replaceWith = "replace it with this string";

#12

wonderful - thanks for the quick response!


#13

Sorry, more nubie questions - this seems to work on a single instance, but does not seem to replace all instances. Ideas?


#14

That is true. The Javascript replace function will only replace one occurrence if you pass a string. You need to pass it as a regex with the “g” flag for a global replace. You don’t need to know any regex in most cases, however, just pass the string like:

/find this string/g

If you have special characters in the string that regex uses, you might hit problems because they would need to be escaped. Like “.” you would have to write as “.”


#15

I’ve just got to mention that this is the perfect sort of problem to kick off learning just a little javascript.

I started with regex and basic find and replace sorts of things. The satisfaction you get from making yourself a truly custom and useful tool is amazing. And Drafts is, I think, an ideal playground to learn this stuff.


#16

Hi there - I’m finally back to this, and am hitting some dead ends. I wondered if anyone can help me here? I’m trying to translate annotations brought into drafts from PDF expert into text that can then be exported to bookends and then as into single text files in Devonthink (the “Split at Delimiter” action is a life saver!).

But I’m having a tough time getting my regex to work. I want to take chunks of text that look like this:

“highlight [page 17]: As a result, the idea that techniques are uncomplicatedly grasped, related to the efficient exploitation of materials can be questioned, a point also made by various anthropologies of technology over the previous two decades (e.g. Lemonnier 1993).
highlight [page 19]: Here, note how only scientific analysis can determine whether distant cherts were objectively…”

and have them transformed to this:

#@17
As a result, the idea that techniques are uncomplicatedly grasped, related to the efficient exploitation of materials can be questioned, a point also made by various anthropologies of technology over the previous two decades (e.g. Lemonnier 1993).

#@19
Here, note how only scientific analysis can determine whether distant cherts were objectively…

So I am trying to do two find and replaces. The first takes “Highlight [page” and replaces it with “#@”. The second to take “]:” and replaces it with a carriage return. I can do this without any problem in the “find and replace” process, but having an action would speed things up. I seem to be having a real battle with the square brackets here: “[” doesn’t seem to get the action to work.

Any ideas?


#17

Usually you escape regex by using a slash: \[

I have a similar action that might be useful to look at: link. But I just strip out the whole line so I don’t need to deal with the brackets.


#18

Hi - thanks (but link doesn’t seem to be working). I am really rough with Regex, so I suspect I’m doing something silly here…


#19

https://regex101.com/ is a good site to test out RegEx when working on scripts, but it looks to me like there might be a space between the slash and the bracket in your script?


#20

Nope, no space there. Hmmm. Can you share the link your action again? Perhaps it can give me some leads…