Does the clipboard starts with a decimal?

I know this must be a simple solution. But it takes me too long to find my answer.

How do I determine if my system clipboard starts with a decimal?

You could do something like this:

09-pty-fs8

Test clipboard for starting with a decimal number.kmmacros (2.2 KB)

Yes yes. That’s it. Thanks!

Or this (which does the same):

09-pty-fs8

Test clipboard for starting with a decimal number (ver 2).kmmacros (2.5 KB)

Variations for the regex (all the same, practically):

\p{Nd}
\p{Decimal_Number}
\p{digit}
\p{General_Category=Decimal_Number}
\p{gc=Nd}
\p{gc=digit}
[0-9]
[:digit:]

Precede with ^ to match only at the beginning of the string.

@Tom, you don’t like the simplest?
\d

Thanks for the tips! I want to expand my macro with this method. How do I delete lines starting with a digit from a clipboard text?

I was mistaken. The lines starting with a digit needs to stay. The other lines (not starting with a digit) need to be deleted.

Here's one way:

Search and Replace.kmactions (465 Bytes)
image

Regex: (?m)^\d.*\n

Thanks for your reply. Somehow it doesn't change my clipboard. Here's the piece of text I want to change:

021  20170624 V     C        14:23:37:11 14:23:38:20 01:02:12:01 01:02:13:10  
021        BL V     D    025 00:00:00:00 00:00:01:00 01:02:13:10 01:02:14:10  
* EFFECT NAME: CROSS DISSOLVE
* FROM CLIP NAME:  PERFECT CADEAU0922.MOV

022        BL V     C        00:00:00:00 00:00:00:00 01:02:15:20 01:02:15:20  
022  20161014 V     D    025 11:28:23:07 11:28:33:09 01:02:15:20 01:02:25:22  
* EFFECT NAME: CROSS DISSOLVE
* TO CLIP NAME:  PERFECT CADEAU0020.MOV

023  20160728 V     C        10:28:25:14 10:28:31:08 01:02:25:22 01:02:31:16  
* FROM CLIP NAME:  PERFECT CADEAU0006.MOV

024  20160728 V     C        15:25:47:00 15:25:49:07 01:02:31:16 01:02:33:23  
* FROM CLIP NAME:  PERFECT CADEAU0036.MOV

025  20160728 V     C        14:59:13:22 14:59:19:00 01:02:33:23 01:02:39:01  
* FROM CLIP NAME:  PERFECT CADEAU0031.MOV

026  20161015 V     C        10:58:21:09 10:58:34:08 01:02:39:01 01:02:52:00  
* FROM CLIP NAME:  PERFECT CADEAU0085.MOV

I was mistaken. The lines starting with a digit needs to stay. The other lines (not starting with a digit) need to be deleted.

Not sure why the last macro action didn't seem to have an effect on your clipboard, as it worked fine on mine. At any rate, here's a full macro designed to delete the opposite kind of line:

Delete Lines Not Starting With Decimal.kmmacros (3.4 KB)
image

Regex: (?m)^\D(?!\d).+(?:\n|\z)

Results:

021 20170624 V C 14:23:37:11 14:23:38:20 01:02:12:01 01:02:13:10
021 BL V D 025 00:00:00:00 00:00:01:00 01:02:13:10 01:02:14:10

022 BL V C 00:00:00:00 00:00:00:00 01:02:15:20 01:02:15:20
022 20161014 V D 025 11:28:23:07 11:28:33:09 01:02:15:20 01:02:25:22

023 20160728 V C 10:28:25:14 10:28:31:08 01:02:25:22 01:02:31:16

024 20160728 V C 15:25:47:00 15:25:49:07 01:02:31:16 01:02:33:23

025 20160728 V C 14:59:13:22 14:59:19:00 01:02:33:23 01:02:39:01

026 20161015 V C 10:58:21:09 10:58:34:08 01:02:39:01 01:02:52:00

Just make sure the the Search and Replace action searches the system clipboard instead of the test variable (and that the text in question is in the clipboard beforehand) and see if that doesn't do the trick.

Hi, sorry for my late respons. Something came up. Now I can resume this macro. Thanks for all your effort so far. I downloaded your complete macro. Unfortunately it gave a different outcome on my machine. (screenshot 1)

When adding a replacement text instead of a blank, results that only at the end the replacement text has been placed. Maybe this will help to solve. (screenshot 2)

FWIW a couple of Execute as Script versions – not sure if this is the kind of output you are after:

PurgeUnnumberedLines.kmmacros (38.6 KB)

Javascript version

(() => {
    'use strict';

    // main :: IO () -> IO String
    const main = () => {
        const
            sa = standardAdditions(),
            s = numberedLinesOnly(
                sa.theClipboard()
            );
        return (
            sa.setTheClipboardTo(s),
            s
        );
    };

    // numberedLinesOnly :: String -> String
    const numberedLinesOnly = s =>
        unlines(
            filter(
                x => 0 < x.length && isDigit(x.charAt(0)),
                lines(s)
            )
        );

    // GENERIC FUNCTIONS ----------------------------------

    // https://github.com/RobTrew/prelude-jxa

    // filter :: (a -> Bool) -> [a] -> [a]
    const filter = (f, xs) => xs.filter(f);

    // isDigit :: Char -> Bool
    const isDigit = c => {
        const n = ord(c);
        return n >= 48 && n <= 57;
    };

    // lines :: String -> [String]
    const lines = s => s.split(/[\r\n]/);

    // ord :: Char -> Int
    const ord = c => c.codePointAt(0);

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // JXA ------------------------------------------------

    // standardAdditions :: () -> Application
    const standardAdditions = () =>
        Object.assign(Application.currentApplication(), {
            includeStandardAdditions: true
        });

    // MAIN ---
    return main();
})();

Applescript version

use scripting additions

on run
    set s to numberedLinesOnly(the clipboard)
    set the clipboard to s
    return s
end run

-- numberedLinesOnly :: String -> String
on numberedLinesOnly(s)
    script initialDigit
        on |λ|(x)
            0 < length of x and isDigit(item 1 of x)
        end |λ|
    end script
    
    unlines(filter(initialDigit, |lines|(s)))
end numberedLinesOnly


-- GENERIC FUNCTIONS ----------------------------------

-- https://github.com/RobTrew/prelude-applescript

-- filter :: (a -> Bool) -> [a] -> [a]
on filter(f, xs)
    tell mReturn(f)
        set lst to {}
        set lng to length of xs
        repeat with i from 1 to lng
            set v to item i of xs
            if |λ|(v, i, xs) then set end of lst to v
        end repeat
        return lst
    end tell
end filter

-- isDigit :: Char -> Bool
on isDigit(c)
    set d to (id of c) - 48 -- id of "0"
    d ≥ 0 and d ≤ 9
end isDigit

-- lines :: String -> [String]
on |lines|(xs)
    paragraphs of xs
end |lines|

-- Lift 2nd class handler function into 1st class script wrapper 
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- ord :: Char -> Int
on ord(c)
    id of c
end ord

-- unlines :: [String] -> String
on unlines(xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set str to xs as text
    set my text item delimiters to dlm
    str
end unlines
1 Like

This macro definitely works as intended on my High Sierra 10.13.5 machine, so I'm not immediately sure what the problem could be for you. What version of macOS are you on? If it's several versions old, it could be that this particular regex isn't supported by the system.

Perhaps the line endings are not LF ?

This works for me, and should handle any end-of-line characters:
(?:\r?\n|\r|$)

I used a two-step process:

  1. Remove all blank lines
    • Search For: (?:\r?\n|\r)(?:\r?\n|\r)
    • Replace With: \n
  2. Remove all lines that don't start with a digit
    • Search For: (?m)^[^\d\n\r].*?(?:\r?\n|\r|$)
    • Replace With: <nothing>

Example Results

image


MACRO:   Remove Lines That Don't Start with a Digit @RegEx [Example]

~~~ VER: 1.0    2018-07-03 ~~~

DOWNLOAD:

Remove Lines That Don't Start with a Digit @RegEx [Example].kmmacros (6.3 KB)
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.


image


Please let us know if this works for you, or if you have questions?

Solved! That two step method worked. I don't have the knowledge to know exactly why but it works on my machine. Maybe its the End of line character that GGlick wrote. Many thanks!

I actually did two things different from the other RegEx solutions:

  1. I used an expression that will match ALL newline Characters in every RegEx engine I know of:
    (?:\r?\n|\r)
    • In the most recent RegEx Engines (like KM 8.2 using macOS 10.11+), you can also use this simpler expression:
      \R
  2. I first removed all blank lines, which made the second RegEx Search simpler

My second RegEx is also different from @gglick's, but I think his works almost as well, perhaps a tiny bit slower (191ms vs 2ms):

  • JMichaelTX: (?m)^[^\d\n\r].*?(?:\r?\n|\r|$)
  • gglick: (?m)^\D(?!\d).+(?:\n|\z)

The only problem with @gglick's is that if you have a CR (\r), or a CRLF (\r\n) in your source text, I think it will fail. Note that when you paste source text into any web page all newline characters are converted to just \n. This includes the RegEx tool that I use, RegEx101.com. So it is hard to test for CR characters. This is a tricky problem.

IAC, I'd glad you have a solution that works for you!