Add a the word "and" before the last word in a list of words?

I have created a workflow that helps me with entering a list of symptoms for a patient. After I enter the list, the output is a list of symptoms separated by a comma. I cannot figure out how to add "and" prior to the last variable. I was thinking of using a simple RegEx Find and Replace on the Variable itself but some of the symptoms variables contain more than one word.

The scoring for the BDI list in my template is 0-3 in case you want to try it.

Test - BDI Symptoms.kmmacros (119 KB)

One approach would be to use an Execute JavaScript for Automation action, adjusting the source and target variable names in the JS code below:

(() => {
    'use strict';
    
    // init :: [a] -> [a]
    const init = xs => xs.length > 0 ? xs.slice(0, -1) : undefined;
    
    // last :: [a] -> a
    const last = xs => xs.length ? xs.slice(-1)[0] : undefined;

    const
        kme = Application('Keyboard Maestro Engine'),
        
        strCommaDelimited = kme.getvariable(
            'someVarName'   // EDIT SOURCE VARIABLE NAME
        ),
        
        lstWords = strCommaDelimited.split(/,\s*/g),
        strAndInserted = init(lstWords).join(', ') + ', and ' + last(lstWords);
    
    return (
        kme.setvariable(
            'otherVarName',   // EDIT TARGET VARIABLE NAME
            {to: strAndInserted}
        ),
        strAndInserted
    );
})();

I'm not clear on your requirements without a good, explicit example of before/after, but maybe this will help.

This will insert "and " prior to the last word:

Search for: (\w+)$
Replace with: and \1

image

Example Results

image

1 Like

At which point would I insert the Javascript?

The challenge with a simple RegEx is that some of my variables contain multiple words in it. For example, a variable can be “pessimism” or “tiredness or fatigue”.

Before:

- Mildly bothered by sadness, pessimism, past failure, loss of pleasure, guilty feelings, self-dislike, suicidal thoughts or wishes, crying, loss of interest, worthlessness, loss of energy, changes in sleeping patterns, changes in appetite, tiredness or fatigue, loss of interest in sex.
After:

- Mildly bothered by sadness, pessimism, past failure, loss of pleasure, guilty feelings, self-dislike, suicidal thoughts or wishes, crying, loss of interest, worthlessness, loss of energy, changes in sleeping patterns, changes in appetite, tiredness or fatigue, and loss of interest in sex.

I haven't tested your macro, but presumably at the end. Does this work (below) ?

Test - BDI Symptoms (ANDification).kmmacros (120.8 KB)

It does not.

If you want to summarise when and where and in what form the data is gathered, we may be able to help you. Probably faster for you to do than for others :slight_smile:

I attached my KM workflow in my initial post. Once the Prompt For Data Input pops up, I enter the score between 0-3. If the score is 0 then the variable is set to be empty. If the score is between 1-3, the variable is set to its name in either mild, moderate, or sever section. The output is then pasted into something like this:

- Mildly bothered by sadness, pessimism, past failure, loss of pleasure.

I then manually look at the entered data and add a “and” before the last comma. The problem is that the last variable in the sentence can be a single word or a combination of words like in the example above.

Then this RegEx Should work:

Search for:
(?m),([\w ]+.?)$

Replace with:
, and\1

For details, see:

Example Results

image

1 Like

Hey Guys,

To solve this sort of problem I’ll do something like this for simplicity.

Step 1:

Collate answers as paragraphs:

Description, with commas, one
Description, with commas, two
Description, with commas, three
Description, with commas, four
Description, with commas, five

Find and replace to prefix the last line with “and”:

Find:

(?m)^(.+\Z)

Replace

and $1

Then find and replace the linefeeds with comma-space:

Find:

\n

Replace

,<space>

I may also do more passes with regex to remove any possible double-spaces and/or other junk in the finished text.

-Chris

Thank you! I made a small modification and it works!

Find

(?m),([\w ]+)(,?\s.?)$

Replace with

, and\1.

Chris, for "simplicity"? LOL
You process takes more steps than mine, which requires only 1 step:

[quote="JMichaelTX, post:10, topic:9635"]
Search for:
(?m),([\w ]+.?)$

Replace with:
, and\1
[/quote]

Yep.

Using this method I don't have to worry in any way about punctuation.

The method scales to many sorts of parsing problems.

-Chris

Well, IMO, it may be more comprehensive, but it is not simpler (your 3+ steps to my 1 step).
I try to provide the simplest solution given the requirement, which in this case was: