Replace text help

What I am trying to do: I want something to copy a link, then search the link, then replace what is in the link with out touching the rest of the link. If that is not confusing enough.

Example: LINK: http://l.corp.help.com/help/me.php?mod=jp_james:thank you

I would like it to copy that link then remove everything between mod= and the “:”

So it would remove jp_james.

Then there would be a input so I can replace it.

I would really like it if there could be a drop down menu that would add the jp_ part of it. The drop down would have jp_/ch_/ko_. So there would be multiple choices including non.

Also maybe if it can show me what the link will be while I type the name and make my selection. then at then end a simple paste command.

I hope someone can help and understand what I just said.

Bonus: if it could remember the last name I typed so all I have to do is change the drop down menu to the correct one that would be great.

Hey James,

Copy a link from where?

The search/replace is easy enough using a regular expression with the Search and Replace Variable action.

Find:

^(http.+?mod=)[^:]+

Replace:

$1<your-text>

The Prompt for User Input action is pretty flexible:

https://wiki.keyboardmaestro.com/action/Prompt_for_User_Input

Keyboard Maestro can’t do that as you type.

Saving variables is simple.

-Chris

So the link will be in a clipboard. I have it copying the link to a clipboard names link_viewer.

So it does not need to “find” the link it will already be in the clipboard.

The link looks like this

http://m.corp.domain.com/tra/fb.php?mod=CHS_James: Knowledge Check

I understand what you said so far and thank you for that. Would you be able to create the macro so I can see what it looks like?

So far I have it copying the link to clipboard= Link_Viewer
Then a search and replace though I am not sure how to tell it to replace with user prompt.

Sorry I am still very new to KM and still learning. Thank you so much as you help me with all my questions so far!

Chris, as you know I'm trying to learn RegEx. So I saw your example here as a great learning opportunity. Your solution, of course, works perfectly.

In the course of analyzing this, the following questions occured to me:

  1. What if the URL was not a standard "http" ?
  2. What if the post variable ("mod") was not in the first position, and thus started with a "&"

So, I experimented a little, and came up with this alternate RegEx that:

  1. Allows the "mod" to be preceded by either "?" or "&"
  2. Does not care what precedes that
  3. Basically will match all characters between "mod" and ":", allow that group to be discarded while using the match groups $1 and $3 on either side of that.

In the KM Search For box:
^(.+[?&]mod=)(.+)(:.+)

In the Replace with box:
$1%Variable%NewName%$3

I'd love to have your assessment of this when you have time.

Here's my macro:

Nikao, if the link is already on the clipboard, then all you need in KM at the start of your macro is the Set Variable to clipboard action:

Then you can use the actions that either Chris or I provided to replace the name string.

At the end of your macro, use the Set Clipboard to Variable action:

Of course you will need to adjust the KM variable name to something you like. I used "Test1" in this example.

As I said before I am still pretty new. Can you explain why this does not work?

You don't need the "Link_Viewer" clipboard in this macro.
Remove all actions that use it.

Replace the 2nd action with:
Copy action (copies selected text to the system/default clipboard)

%Variable%Country%Owner% is NOT a valid variable/token:

If you are trying to combine the two variable from your Prompt above, it would be:
$1%Variable%Country%%Variable%Owner%$3

Delete the last 2 actions.
ADD to the end:
Set Clipboard to Text action, just like I did in my above post.

This results in the modified link being on the clipboard, which you can paste anywhere.

If this is still not working, add this action to the bottom, and copy/paste the results into your post here.

Thank you! It is now working.

Two things left:

  1. There is not always a country so is there a way to add a blank in the drop down menu
  2. I want it to save the last spot of the drop down menu and the last name I used for the Owner field.

I found how to make it blank by just using two || so now I am just trying to get it to save the last settings used

How do you save the last variables used in a User Input prompt?

Thanks all!! I did find out how to save what was put there last. Thanks again!

Nikao, I see you figured it out.

For any other readers having this question, the answer is that the Variable is automatically saved in your KM variable environment. The real question is, how to show the last value of that variable in the Prompt for Input.

The answer is: enter the variable token in the default value field:

Maybe you can answer something else for me.

There is a second area that I have to change the name. But this area is in code. So what I did was copy the whole macro then tried to change the copy and replace (since I want it to do that same thing) but it did not work

The portion that it needs to be replace looks like this

<owner><![CDATA[James]]></owner>

So How would I tell it to find and replace where James is? Its not always going to say James. So I was trying to find and replace the following.

"owner>< /owner>

(I had to add a space after the < and before the / for it to show up in this page)

###This uses the same general RegEx pattern as before:
(<owner><!\[CDATA\[)(.+)(\]\]><\/owner>)

Notice that the ( ) bound the match groups involved:
$1 -- group preceding the text you want to replace
$2 -- group that you want to replace (which can be anything: (.+)
$3 -- group following the text you want to replace

###Here's an example macro, that you should now be able to use to compose the actual macro you need:

I think you are misunderstanding @ccstone’s regex.

^(http.+?mod=)[^:]+

.+? does not search for one or more characters and then a ?

It searches for one or more characters but not greedily. That is, the first use of mod= after one or more characters.

The difference occurs in matching cases like this:

httpABCmod=DEFmod=HIJ

If you match http.+mod=(.*), then the capture will be “HIJ”.

If you match http.+?mod=(.*), then the capture will be “DEFmod=HIJ”

So @ccstone’s regex will not require a ? or an & before the mod, but it will require the = after it. So this might fail in a case like:

http://whatever/whatever?mymod=abc&mod=def

But it will fail because of the earlier matching “mod=”, not because of the ? or &.

Yours “^(.+[?&]mod=)(.+)(:.+)” on the other hand would fail in a case like this:

http://whatever/whatever?mod=abc:def&mymod=hij:klm

Your (.+) will capture “abc:def&mymod=hij”

Regular expressions will almost always have some sort of limitations when parsing URLs - the trick is really just ensuring it will match and correctly behave with the URLs that you are likely to see.

1 Like

No doubt there is much I don’t understand about RegEx.
Thanks, Peter, for taking the time to edify me, and hopefully many others.

So, as I understand it, using @ccstone’s pattern of ^(http.+?mod=)[^:]+ , the following will misidentify (match):
http://l.corp.help.com/help/me.php?type=testmod=jp_james:thank you

since it does NOT require either a “&” nor a “?” prior to the “mod=”.

Since the OP was looking for a post variable of “mod”, shouldn’t either a “?” or a “&” be required for a correct match?

If so, how do you do this?

RegEx is such a black magic I want to acquire! :sunglasses:

Hey JM,

Given Nikao’s original URL I think that shouldn’t be a problem, however there are certainly other circumstances where it could be.

Can we make this pattern more bombproof? Sure:

Find:

^(http.+?\.php\?mod=)[^:]+

Replace:

$1<your-text>

When you want to use a reserved character as a literal you have to escape it.

So ? becomes \? and . becomes \.

In this case we’re looking for a simple HTTP URL, although the pattern will also handle HTTPS.

Oh, I should have mentioned the search/replace should be case-insensitive.

Regular Expression (ignoring case) for:

My cheatsheet for BBEdit and TextWrangler is fairly handy when you’re still learning regex vocabulary.

BBEdit-TextWrangler_RegEx_Cheat_Sheet

The biggest thing you have to remember when moving between Keyboard Maestro and BBEdit or TextWrangler is to change the capture format from:

BBEdit & TextWrangler

\1\2\3

Keyboard Maestro

$1$2$3

-Chris

3 Likes

Thank you all. Everything is working great!

Thanks for the feedback, Chris. Very helpful to many, especially me.

Thanks for sharing. Excellent guide. :+1:

Hey JM,

It’s always nice when a macro is posted as well as the graphics, so it can be downloaded and tested verbatim.

Your pattern:

^(.+[?&]mod=)(.+)(:.+)

Will match this:

Example: LINK: http://l.corp.help.com/help/me.php?mod=jp_james:thank you

As well as this:

http://l.corp.help.com/help/me.php?mod=jp_james:thank you

Not this:

http://l.corp.help.com/help/me.php?type=testmod=jp_james:thank you

If I was trying to make it a little more generic I’d probably do something like this:

^([[:alpha:]]+://.+?[?&]mod=)(.+?)(:.+)

The ? characters NOT in the range box ( e.g. NOT [?&] ) are the non-greedy operator.

Be sure to absorb and understand the concepts of greedy vs non-greedy matches.

-Chris

1 Like