I had a macro that was working on one Mac, and then when I synced it with a new Mac it doesn’t work anymore. What I want to do is to copy some text from Microsoft Todo (the notes section of a task) and create variables from that text which I then use to search in Outlook.
Here is an example of the text:
To: servicedesk@somecompany.com
Subject: Parking space
Time: 2020-11-03T14:18:39+00:00
---------------------------------------------
Hi!
I'd like to reserve a parking spot.
I use this regexp expression which works fine on https://regex101.com:
\A(.+)(\n+)(.+)(\n+)([\s\S]+)
My problem is that this only works when I copy the text from for example TextEdit, whenever I copy the text from Microsoft ToDo the capture groups are not put into variables.
I try to display the system clipboard in case the text was cached on not copied correctly, but the window shows the copied text.
First, I'd encourage you to continue learning RegEx. IMO it is one of the most powerful and useful languages you can learn. You can use it just about everywhere. If you want more info on RegEx, just ask.
I'm not sure why this works for you in TextEdit and not MS ToDo, but it could be the newline character (CR vs LF).
Sometimes it is easier and more reliable to use a separate RegEx Search for each variable. And that is what I have done in this example Macro.
Example Results
Below is just an example written in response to your request. You will need to use as an example and/or change to meet your workflow automation needs.
OK, that source does indeed delimit lines on Windows-style '\r\n', rather than the '\n' assumed in your regular expression patterns,
and it seems that all you are looking for is the Subject: line, and the value following that prefix.
So I would personally:
clamber out of the regex tar-pit
split the lines on \r\n
find the the first line that starts with 'Subject: ', and take the rest of it.
You could do this in AppleScript or JS.
Here, FWIW, is a JS version, with source code, for pasting into a KM Execute JXA action, below:
Copy all of this and paste into the Execute JavaScript for Automation action:
(() => {
'use strict';
ObjC.import('AppKit');
const main = () => {
const
xs = lines(clipboardText()),
subjectLine = xs.find(
x => x.startsWith('Subject: ')
);
return undefined !== subjectLine ? (
subjectLine.split(': ')[1]
) : 'Subject not found ...'
};
// ----------------------- JXA -----------------------
// clipboardText :: IO () -> String
const clipboardText = () =>
// Any plain text in the clipboard.
ObjC.unwrap(
$.NSString.alloc.initWithDataEncoding(
$.NSPasteboard.generalPasteboard
.dataForType($.NSPasteboardTypeString),
$.NSUTF8StringEncoding
)
);
// lines :: String -> [String]
const lines = s =>
// A list of strings derived from a single
// string delimited by newline and or CR.
0 < s.length ? (
s.split(/[\r\n]+/)
) : [];
return main();
})();
As a footnote, although I personally reach first for JS to define something like:
The first line that starts with "Subject:"
we can readily define the same thing directly in terms of the building blocks that @peternlewis provides in Keyboard Maestro.
In particular, I notice that:
when the For Each action works through the lines of a variable or clipboard, it is not bamboozled by that difference between Windows-style and macOS or Unix-style endings which you have to get right in a regular expression.
Others will be better-practiced in the choice of these actions, but this kind of thing seems to define exactly the same pattern as the JavaScript:
I like this method! But I'm not able to replicate it; the window that should contain the variable subjectValue is empty. Not sure if I perhaps have the action Get Substring of Variable "subjectText" misconfigured, perhaps you can expand that section?
Also, I'm not sure I completely follow the logic: where is lineText defined in the condition "For each lineText in these collections"? Shouldn't I need to first put each line in clipText into the variable lineText, and then check it?
And the variable subjectValue is not defined anywhere except for in the display text action at the end, where is this value populated?
Note that the "delete to" option at the end of the loop is used to remove the "Subject:" prefix if needed, I use it since the old and new Outlook for Mac works differently with regards to search parameters.