Problem to Solve.kmmacros (6.8 KB) I created a variable containing a text from a webpage and try to extract a group of text with a specific code using Regular Expression. But the problem I want to get specific code only from a variable. I will show my macro so it is easy to understand.
So this is macro
Prompt for User Input “Code”
Save to Variable Name: code
232
Execute AppleScript
Save to Variable name: Comment
1
Sorry, we're having trouble playing this video.
Belina Daan Gasco is live now in Test.
Just now ·
1 Comment
Like
Comment
Comments
Hide
Comments
Belina Daan Gasco
mine 232
Like
· Reply · Pin · 1m
Write a comment...
Prime Gasco
mine 261
Like
· Reply · Pin · 1m
Write a comment...
Chlo Daan
mine 241
Like
· Reply · Pin · 1m
Write a comment...
1
93
Your comment was submitted
Search Variable “Comment” Using Regular Expression (ignoring case)
Regex
(.+
.+mine\s+\d+).+|(.+
.+\d+\s+mine.+)
Here is the Problem I want to insert Variable in my Regex but how?
I want to like this:
Generally quicker to write and easier to maintain in terms like this:
s.startsWith('mine ') && s.endsWith(numberString)
You have to learn a little JavaScript, or something similar, but it doesn't take nearly as long as the sum of all that Regex-fiddling development and down-time
Thank you, your solution is quicker than mine, I solve it also but using Regex with For functions. It takes 10 secs to get the result lol. Thank you, I will use this. and I will practice JavaScript.
By the way there are problems, if a person type "mine 232 please!" the javascript you made is not working and if a person type please "Please mine 232" or "232 mine please"? do you have another solution for this? @ComplexPoint
(() => {
'use strict';
const main = () => {
const
kme = Application('Keyboard Maestro Engine'),
[inputText, numberString] = [
'inputText', 'numberString'
]
.map(k => kme.getvariable(k));
const
lineList = lines(inputText),
linePairs = zip(lineList)(
tail(lineList)
);
return maybe(
// Failure.
'Not found: ' + numberString
)(
// Success.
ab => {
// The name is the first line of
// a two-line pair.
const name = fst(ab);
return (
// Effect.
kme.setvariable('FBFilter', {
to: name
}),
// Value.
name
)
}
)(
// Search.
find(
ab => {
const s = snd(ab);
// Instead of:
// return s.startsWith('mine ') && (
// s.endsWith(' ' + numberString)
// )
return s.includes('mine') && (
s.includes(numberString)
)
}
)(
// Each line zipped together with
// the following line.
zip(lineList)(
tail(lineList)
)
)
)
};
// ------------- GENERAL LIBRARY FUNCTIONS -------------
// https://github.com/RobTrew/prelude-jxa
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
// find :: (a -> Bool) -> [a] -> Maybe a
const find = p =>
// Just the first element in xs which
// matches the predicate p, or
// Nothing if no match is found.
xs => xs.constructor.constructor.name !== (
'GeneratorFunction'
) ? (() => {
const
ys = list(xs),
i = ys.findIndex(p);
return -1 !== i ? (
Just(ys[i])
) : Nothing();
})() : findGen(p)(xs);
// fst :: (a, b) -> a
const fst = tpl =>
// First member of a pair.
tpl[0];
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
'GeneratorFunction' !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
// lines :: String -> [String]
const lines = s =>
// A list of strings derived from a single
// newline-delimited string.
0 < s.length ? (
s.split(/[\r\n]/)
) : [];
// list :: StringOrArrayLike b => b -> [a]
const list = xs =>
// xs itself, if it is an Array,
// or an Array derived from xs.
Array.isArray(xs) ? (
xs
) : Array.from(xs || []);
// maybe :: b -> (a -> b) -> Maybe a -> b
const maybe = v =>
// Default value (v) if m is Nothing, or f(m.Just)
f => m => m.Nothing ? v : f(m.Just);
// snd :: (a, b) -> b
const snd = tpl =>
// Second member of a pair.
tpl[1];
// tail :: [a] -> [a]
const tail = xs =>
// A new list consisting of all
// items of xs except the first.
'GeneratorFunction' !== xs.constructor
.constructor.name ? (
(ys => 0 < ys.length ? ys.slice(1) : [])(
list(xs)
)
) : (take(1)(xs), xs);
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => 'GeneratorFunction' !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// zip :: [a] -> [b] -> [(a, b)]
const zip = xs =>
// Use of `take` and `length` here allows for
// zipping with non-finite lists - i.e. generators
// like cycle, repeat, iterate.
ys => (([xs_, ys_]) => {
const
n = Math.min(...[xs_, ys_].map(length)),
vs = take(n)(ys_);
return take(n)(xs_).map(
(x, i) => Tuple(x)(vs[i])
);
})([xs, ys].map(list));
// MAIN ---
return main()
})()
Now it works in any combination of string, You are a Genius, I cannot fully understand the javascript compare to AppleScript, I definitely need to learn this, right now, comparing your two codes, trying to understand. Thank you again. @ComplexPoint
Just add one more note: this RegEx will return only the first match.
If two persons have the same number code (e.g., 232), and you want to find both of them, it will not work. In this case, you will have to use the "For Each" action and the "Append text to Variable" action.
An example may be found here: