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?
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:
Test clipboard for starting with a decimal number.kmmacros (2.2 KB)
Yes yes. That’s it. Thanks!
Or this (which does the same):
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.
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)
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:10022 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:22023 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
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:
(?:\r?\n|\r)(?:\r?\n|\r)
\n
(?m)^[^\d\n\r].*?(?:\r?\n|\r|$)
<nothing>
#### DOWNLOAD:
<a class="attachment" href="/uploads/default/original/3X/4/5/45a781e5cb2a84ebc482ae6f405f40f193ba46d4.kmmacros">Remove Lines That Don't Start with a Digit @RegEx [Example].kmmacros</a> (6.3 KB)
**Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.**
---

---
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:
(?:\r?\n|\r)
\R
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):
(?m)^[^\d\n\r].*?(?:\r?\n|\r|$)
(?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!