How Do I Pad a String With Spaces to Make the Total Characters = 12?

I'm kind of a complete noob on this, so apologies if theses a rather simplistic question:

I have a macro that I need to pad out the clipboard string (which will always end in "EG") with spaces in a specific way. I need the string to be converted to a 12 character string, with spaces padding between the EG and what comes before. So for instance:

"39283EG" should become "39283_____EG", assuming _ is a space character.

How would I accomplish this in formatting? The input strings will vary in length.

Hey Javier,

This is indeed a simple task that can be accomplished a number of ways.

Hammering in a nail is also a simple task, unless you've never done it before – when you find it's more difficult than it looks...

I'm providing an AppleScript example, since it's the easiest/fastest way for me to get the job done.

Space-Pad a String on the Clipboard (AppleScript) v1.00.kmmacros (3.1 KB)

Okay, I was wrong – it was easier to do in Perl.  :sunglasses:

Space-Pad a String on the Clipboard (Perl) v1.00.kmmacros (2.3 KB)

This can also be done with Keyboard Maestro native actions – I'd provide an example, but I don't have time.

  • Copy the system clipboard to a variable.
  • Filter action using Length to another variable.
  • Use the Set Variable to Calculation action to compute the length diff.
  • Etcetera.

Oh, yeah – I'm outputting to a window – but you can change that to the clipboard or a variable.

-Chris

Hi @javierjabanero,

Here's a version that uses JavaScript. It's a macro designed to be called as a SubMacro.
[LIB]_PadAtFront.kmmacros (7.8 KB)

I have one that also adds padding to the end...

Or (again using an Execute JavaScript for Automation action), and aligning in three different ways.

(Here using "x" as a spacer character for visibility, but you would probably want to switch that to " "):

We can get these three variants:

wordxxxxxxxx
xxxxwordxxxx
xxxxxxxxword

from these three functions:

// https://github.com/RobTrew/prelude-jxa
(() => {
    "use strict";

    const main = () => [justifyLeft, center, justifyRight]
        .map(
            f => f(12)("x")("word")
        )
        .join("\n");


    // --------------------- GENERIC ---------------------

    // center :: Int -> Char -> String -> String
    const center = n =>
        // Size of space -> filler Char ->
        // String -> Centered String
        c => s => {
            const gap = n - s.length;

            return 0 < gap ? (() => {
                const pre = c.repeat(Math.floor(gap / 2));

                return pre + s + pre + c.repeat(gap % 2);
            })() : s;
        };

    // justifyLeft :: Int -> Char -> String -> String
    const justifyLeft = n =>
        // The string s, followed by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padEnd(n, c)
        ) : s;

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n =>
        // The string s, preceded by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padStart(n, c)
        ) : s;


    return main();
})();

I have to disagree with my friend Chris @ccstone. I don't think this is a "simple task". But then "simple" is a relative term, and clearly varies with the developer.

IAC, I find that JavaScript for Automation (JXA) to be the easiest to write and read.

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.

Note that this macro/script provides the following:

  1. The script gets all of its data from KM Variables
  2. The pad length is checked to ensure it does NOT exceed the maximum.

Please let us know if it meets your needs.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Example Output

image

image

image


MACRO:   Add Pad To Middle of String [Example]

-~~~ VER: 1.0    2021-05-13 ~~~
Requires: KM 8.2.4+   macOS 10.11 (El Capitan)+
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))

DOWNLOAD Macro File:

Add Pad To Middle of String [Example].kmmacros
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.


ReleaseNotes

Author.@JMichaelTX

PURPOSE:

  • Add Pad To Middle of String
    • Add Pad of SPACE Just Before Specified Characters at end of String

HOW TO USE

  1. First, make sure you have followed instructions in the Macro Setup below.
  2. See the below "How to Use" Comment Action
  3. This macro 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.

MACRO SETUP

  • Carefully review the Release Notes and the Macro Actions
    • Make sure you understand what the Macro will do.
    • You are responsible for running the Macro, not me. ??
      .
      Make These Changes to this Macro
  1. Assign a Trigger to this Macro .
  2. Move this macro to a Macro Group that is only Active when you need this Macro.
  3. ENABLE this Macro, and the Macro Group it is in.
    • For more info, see KM Wiki article on Macro Activation
      .
  • REVIEW/CHANGE THE FOLLOWING MACRO ACTIONS:
    (all shown in the magenta color)
    • SET String at END of Source String
    • SET Max Length of Output String AFTER Pad

REQUIRES:

  1. KM 9.0+ (may work in KM 8.2+ in some cases)
  2. macOS 10.12.6 (Sierra)+

TAGS: @Example @JXA @Pad


JXA Script

'use strict';
var ptyScriptName   = "Add Pad to Middle of String"
var ptyScriptVer     = "1.0"
var ptyScriptDate   = "2021-05-13"
var ptyScriptAuthor = "JMichaelTX"

var app = Application.currentApplication()
app.includeStandardAdditions = true
var kmInst = app.systemAttribute("KMINSTANCE");
var kmeApp = Application("Keyboard Maestro Engine")
 
var endStr     = kmeApp.getvariable("Local__EndString",  {instance: kmInst}) || 'EG';
var sourceStr   = kmeApp.getvariable("Local__SourceString",  {instance: kmInst}) || '39283EG';
var maxLenStr   = kmeApp.getvariable("Local__MaxLength",  {instance: kmInst}) || '12';

var maxLen       = parseInt(maxLenStr, 10);  // convert to integer
var numPad       = Math.max((maxLen - sourceStr.length), 0);  // num of pad characters
var padToAddStr   = ' '.repeat(numPad);  // actual pad string

var reSplit       = new RegExp(endStr + '$')  // RegExp to use in split

// ~~~ Build New String with Pad ~~~
var paddedStr     = sourceStr.split(reSplit)[0] + padToAddStr + endStr;

paddedStr;

Hey Javier,

Okay, here's a version using only Keyboard Maestro native actions – no scripting required.

-Chris


Space-Pad a String on the Clipboard (Keyboard Maestro Native) v1.00.kmmacros (8.3 KB)

Just for fun – here's a Perl 1-liner.

-Chris


Space-Pad a String on the Clipboard (Perl 1-Liner) v1.00.kmmacros (5.8 KB)

Simplified AppleScript:

--------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2021/05/13 13:54
# dMod: 2021/05/13 23:23
# Appl: Keyboard Maestro
# Task: Space-Pad a String on the Clipboard to 12 Characters (simplified).
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Keyboard_Maestro_Engine, @RegEx, @Space, @Pad
# Vers: 1.00
--------------------------------------------------------

set padStr to "               "

set clipboardText to the clipboard
set stringLength to length of clipboardText

if stringLength < 12 then
   set strLenDiff to 12 - stringLength
   set thePad to text 1 thru strLenDiff of padStr
   set newStr to text 1 thru -3 of clipboardText & thePad & text -1 thru -2 of clipboardText
   return newStr
end if

And again for fun with Bash.

I doubt I'd ever use this in real life, but I wanted to see how difficult it would be with pure Bash.

-Chris


Space-Pad a String on the Clipboard (Bash) v1.00.kmmacros (5.9 KB)

Here's a 3-step native KM solution.

1 Like

Hey Steve,

Clever!  :sunglasses:

-Chris

Inspired by Steve's solution – a 2-Action Native Keyboard Maestro Solution.

(The display action doesn't count.)

-Chris


Space-Pad a String on the Clipboard (Keyboard Maestro Native) v2.00.kmmacros (7.9 KB)

1 Like

Chis --

Nice!

Steve

1 Like

Here's a single-action version.

Well done!  :smile:

Here's a downloadable version with the regex rewritten slightly.

-Chris


Space-Pad a String on the Clipboard (Keyboard Maestro Native) v2.50.kmmacros (7.6 KB)

The regular expression could be written a little more simply:

(.+?)(\S{2})(\h{%Calculate%12-CHARACTERS(%SystemClipboard%)%}).*

\1\3\2

Chris --

I believe that fails in the case where there's exactly 10 characters before the EG, but perhaps that's not valid input for Javier. (The 2 previous versions, yours and mine, both did work in that case.)

Steve

Hmm... True.

Try this:

(.+)(\S{2})(\h{%Calculate%12-CHARACTERS(%SystemClipboard%)%}).*

:+1:

Nice playing KM/Regex slam with you. Meanwhile, Javier has moved on to another project. :slightly_smiling_face:

Steve

1 Like

Hey all, I am SO sorry for ghosting you guys, I got really busy with the job for which this Macro was needed, and things have only recently slowed down to the point where I had the bandwidth to revisit workflow stuff. Thank you all for the input and replies, if anything, this thread is telling me that I need to seriously brush up on my RegEx. I'm trying out several of these solutions, thank you all for the help, I really appreciate it.

1 Like