slyfox Posted September 12, 2019 Posted September 12, 2019 (edited) I need a simple workflow to copy text -> use RegEx to replace various text within the clipboard content and paste it back. My current workflow is to simply create a bunch of linked find and replace utility arguments inside Alfred. I am not sure if this is the best approach compared to a simple Javascript that includes a list of variables to replace. I don't know Java or any other programming language but sample Javascript looks simple enough to modify if someone can provide it. Edited September 13, 2019 by slyfox
deanishe Posted September 13, 2019 Posted September 13, 2019 12 hours ago, slyfox said: I am not sure if this is the best approach compared to a simple Javascript that includes a list of variables to replace. A script would certainly be easier to add new items to. 12 hours ago, slyfox said: simple enough to modify if someone can provide it If you post some sample input and the expected output, sure.
slyfox Posted September 13, 2019 Author Posted September 13, 2019 (edited) "If you post some sample input and the expected output, sure." @deanishe Are the examples (i.e., Mr. to Ms.) in the screenshots not clear? Edited September 13, 2019 by slyfox
deanishe Posted September 13, 2019 Posted September 13, 2019 2 hours ago, slyfox said: @deanishe Are the examples (i.e., Mr. to Ms.) in the screenshots not clear? There are no examples in the screenshots. Those are the notes you've added. I can't see the actual contents of the Replace elements.
slyfox Posted September 13, 2019 Author Posted September 13, 2019 (edited) They are the same as the notes. Replace He with She Replace Mr with Ms I am using basic string replace. Edited September 13, 2019 by slyfox
slyfox Posted September 13, 2019 Author Posted September 13, 2019 There is a space after “He “ and “She “
deanishe Posted September 13, 2019 Posted September 13, 2019 (edited) On 9/13/2019 at 6:06 PM, slyfox said: There is a space after “He “ and “She “ 😐 That isn't what you or your screenshots said earlier, is it? Here is a JavaScript that will replace some of your words. It's pretty clear where new entries go. Use it instead of all your Replace utilities. Put it in a Run Script action with Language = /usr/bin/osascript (JS) and with input as argv. #!/usr/bin/osascript -l JavaScript var replacements = [ // (\W|^) matches non-word character or start // (\W|$) matches non-word character or end // $1 and $2 are the first and second match groups, // where a match group is whatever matches the contents // of a pair of parentheses. [/(\W|^)He(\W|$)/gm, '$1She$2'], [/(\W|^)he(\W|$)/gm, '$1she$2'], [/(\W|^)Mr(\W|$)/gm, '$1Ms$2'], [/(\W|^)His(\W|$)/gm, '$1Her$2'], [/(\W|^)his(\W|$)/gm, '$1her$2'], ]; function feminise(s) { replacements.forEach(function(l) { s = s.replace(l[0], l[1]); }); return s; } function run(argv) { return feminise(argv[0]); } Edited January 9, 2020 by deanishe AS -> JS
slyfox Posted September 14, 2019 Author Posted September 14, 2019 @deanishe Thank you for the script. It works. Any idea why when the new content is pasted, there is a new line at the bottom whereas the original content does not have a new line?
deanishe Posted September 14, 2019 Posted September 14, 2019 2 hours ago, slyfox said: Any idea why when the new content is pasted, there is a new line at the bottom whereas the original content does not have a new line? Because osascript adds a newline. Run the output through a Transform utility to remove the extra whitespace.
slyfox Posted January 9, 2020 Author Posted January 9, 2020 I am trying to figure out how to convert a simple Keyboard Maestro (KM) text manipulation workflow into Drafts action. Please note that I don't know Java Script but perhaps with some examples, I can figure out the basics principles of RegEx Find & Replace in Javascript. A plain text document contains an instance of "Mr. John Smith" (name varies) The rest of the document refers to the client as Mr. XX. My KM workflow copies text to clipboard and then runs the RegEx with variables. `/([M][r-s]\.\s)(\w*\s)(\w*)/g;` Where: Group 1 = Mr. Group 2 = John Group 3 = Smith Group 2 is set to variable FirstName Group 3 is set to variable LastName I then tell KM to replace all instances of XX with LastName variable. Based on the solution in this forum post for Find & Replace as well as as this forum post - https://forums.getdrafts.com/t/regex-find-and-replace-with-variables/6294/11?u=slyfox I tried to figure this out myself but it does not seem to be working. Can you please advise how to make this work? #!/usr/bin/osascript -l JavaScript var replacements = [ // (\W|^) matches non-word character or start // (\W|$) matches non-word character or end // $1 and $2 are the first and second match groups, // where a match group is whatever matches the contents // of a pair of parentheses. [/(\W|^)XX(\W|$)/gm, '$1/([M][r-s]\.\s)(\w*\s)(\w*)/)[3]$2'], ]; function feminise(s) { replacements.forEach(function(l) { s = s.replace(l[0], l[1]); }); return s; } function run(argv) { return cleanReport(argv[0]); }
Terminal Posted January 9, 2020 Posted January 9, 2020 1 hour ago, slyfox said: I am trying to figure out how to convert a simple Keyboard Maestro (KM) text manipulation workflow into Drafts action. Please note that I don't know Java Script but perhaps with some examples, I can figure out the basics principles of RegEx Find & Replace in Javascript. A plain text document contains an instance of "Mr. John Smith" (name varies) The rest of the document refers to the client as Mr. XX. My KM workflow copies text to clipboard and then runs the RegEx with variables. `/([M][r-s]\.\s)(\w*\s)(\w*)/g;` Where: Group 1 = Mr. Group 2 = John Group 3 = Smith Group 2 is set to variable FirstName Group 3 is set to variable LastName I then tell KM to replace all instances of XX with LastName variable. Based on the solution in this forum post for Find & Replace as well as as this forum post - https://forums.getdrafts.com/t/regex-find-and-replace-with-variables/6294/11?u=slyfox I tried to figure this out myself but it does not seem to be working. Can you please advise how to make this work? #!/usr/bin/osascript -l JavaScript var replacements = [ // (\W|^) matches non-word character or start // (\W|$) matches non-word character or end // $1 and $2 are the first and second match groups, // where a match group is whatever matches the contents // of a pair of parentheses. [/(\W|^)XX(\W|$)/gm, '$1/([M][r-s]\.\s)(\w*\s)(\w*)/)[3]$2'], ]; function feminise(s) { replacements.forEach(function(l) { s = s.replace(l[0], l[1]); }); return s; } function run(argv) { return cleanReport(argv[0]); } Not super familiar with JS. Does this work? var replacements = [ // (\W|^) matches non-word character or start // (\W|$) matches non-word character or end // $1 and $2 are the first and second match groups, // where a match group is whatever matches the contents // of a pair of parentheses. /(\W|^)XX(\W|$)/gm, ]; function getName(s) { let lastname = /(?:[M][r-s]\.\s)(?:\w+)(\s\w*)/; return s.match(lastname)[1] } function cleanReport(s) { replacements.forEach(function(l) { s = s.replace(l, getName(s)); }); return s; } function run(sb) { return cleanReport(sb); }
slyfox Posted January 9, 2020 Author Posted January 9, 2020 8 hours ago, Terminal said: Not super familiar with JS. Does this work? var replacements = [ // (\W|^) matches non-word character or start // (\W|$) matches non-word character or end // $1 and $2 are the first and second match groups, // where a match group is whatever matches the contents // of a pair of parentheses. /(\W|^)XX(\W|$)/gm, ]; function getName(s) { let lastname = /(?:[M][r-s]\.\s)(?:\w+)(\s\w*)/; return s.match(lastname)[1] } function cleanReport(s) { replacements.forEach(function(l) { s = s.replace(l, getName(s)); }); return s; } function run(sb) { return cleanReport(sb); } It does not.
Terminal Posted January 9, 2020 Posted January 9, 2020 (edited) Can you post a same paragraph for me to test on. this appears to work for me. #!/usr/bin/osascript -l JavaScript var replacements = [ // (\W|^) matches non-word character or start // (\W|$) matches non-word character or end // $1 and $2 are the first and second match groups, // where a match group is whatever matches the contents // of a pair of parentheses. [/(\W|^)He(\W|$)/gm, '$1She$2'], [/(\W|^)he(\W|$)/gm, '$1she$2'], [/(\W|^)Mr(\W|$)/gm, '$1Ms$2'], [/(\W|^)His(\W|$)/gm, '$1Her$2'], [/(\W|^)his(\W|$)/gm, '$1her$2'], [/(\W|^)Him(\W|$)/gm, '$1Her$2'], [/(\W|^)him(\W|$)/gm, '$1her$2'], ]; var nameReplacement = /(\W|^)XX(\W|$)/gm; function getName(s) { let lastname = /(?:[M][r-s]\.\s)(?:\w+)(\s\w*)/; return s.match(lastname)[1] } function feminise(s) { replacements.forEach(function(l) { s = s.replace(l[0], l[1]); }); s = s.replace(nameReplacement, getName(s)); return s; } function run(argv) { return feminise(argv[0]); } Edited January 9, 2020 by Terminal
deanishe Posted January 9, 2020 Posted January 9, 2020 9 hours ago, slyfox said: It does not. This is not a useful answer. @Terminal is very kindly spending their time helping you, but you are not being helpful in return. When something doesn't work, explain exactly why it doesn't work. What was the input, what was the output, and what was the expected output?
slyfox Posted January 9, 2020 Author Posted January 9, 2020 @Terminal Almost there. @deanishe Sorry, I'll be more specific. input: Mr. John Smith Mr. XX goes to town. Output: Mr. John Smith Mr. Smithgoes to town. Javascript used #!/usr/bin/osascript -l JavaScript var replacements = [ ]; var nameReplacement = /(\W|^)XX(\W|$)/gm; function getName(s) { let lastname = /(?:[M][r-s]\.\s)(?:\w+)(\s\w*)/; return s.match(lastname)[1] } function cleanup(s) { replacements.forEach(function(l) { s = s.replace(l[0], l[1]); }); s = s.replace(nameReplacement, getName(s)); return s; } function run(argv) { return cleanup(argv[0]); } Can I also ask (trying to understand) 1. Why do we need line 2-5? Can't we just start with line var nameReplacement = /(\W|^)XX(\W|$)/gm; 2. return s.match(lastname)[1] --> Why is there a number 1 rather then number 3? I thought that the last name will be group $3 in RegEx
Terminal Posted January 9, 2020 Posted January 9, 2020 51 minutes ago, slyfox said: @Terminal Almost there. @deanishe Sorry, I'll be more specific. input: Mr. John Smith Mr. XX goes to town. Output: Mr. John Smith Mr. Smithgoes to town. Can I also ask (trying to understand) 1. Why do we need line 2-5? Can't we just start with line var nameReplacement = /(\W|^)XX(\W|$)/gm; 2. return s.match(lastname)[1] --> Why is there a number 1 rather then number 3? I thought that the last name will be group $3 in RegEx This should fix it. And to answer your questions 1. I left replacement because I wasn't full sure of your use case. I remove the unneeded code. 2. return s.match(lastname)[1] works because of the regex we are using /(?:[M][r-s]\.\s)(?:\w+\s)(\w*)/ The ?: in the capture groups "()" tells the regex parser to ignore the grouping. Basically, look for this pattern as a group, but ignore it when returning matches. so we use [1] because [0] contains the full match and [1] contains the match we asked for. #!/usr/bin/osascript -l JavaScript var nameReplacement = /(\W|^)XX(\W|$)/gm; function getName(s) { let lastname = /(?:[M][r-s]\.\s)(?:\w+\s)(\w*)/; return s.match(lastname)[1] } function cleanup(s) { s = s.replace(nameReplacement, "$1"+getName(s)+"$2"); return s; } function run(argv) { return cleanup(argv[0]); }
slyfox Posted January 10, 2020 Author Posted January 10, 2020 @Terminal Through some trial and error I am trying to add another RegEx find & Replace but so far nothing happens. This time I am trying to replace "DOB" with "Date of Birth: January 10, 2020" All instances of "DOB" should turn into "January 10, 2020" Also, how would you combine multiple find and replace scripts into one? #!/usr/bin/osascript -l JavaScript var dobReplacement = /(\W|^)DOB(\W|$)/gm; function getDateofBirth(s) { let dob = /(?:Date\sof\sBirth:\s)?:(\w+\s\d{1,2}\,\s\d{4})/; return s.match(dob)[1] } function replaceDOB(s) { s = s.replace(dobReplacement, "$1"+getDateofBirth+"$2"); return s; } function run(argv) { return cleanup(argv[0]); }
deanishe Posted January 10, 2020 Posted January 10, 2020 4 minutes ago, slyfox said: s = s.replace(dobReplacement, "$1"+getDateofBirth+"$2"); You're trying to replace text with a function. Not the result of calling a function. A literal function.
Terminal Posted January 10, 2020 Posted January 10, 2020 3 minutes ago, slyfox said: @Terminal Through some trial and error I am trying to add another RegEx find & Replace but so far nothing happens. This time I am trying to replace "DOB" with "Date of Birth: January 10, 2020" All instances of "DOB" should turn into "January 10, 2020" Also, how would you combine multiple find and replace scripts into one? #!/usr/bin/osascript -l JavaScript var dobReplacement = /(\W|^)DOB(\W|$)/gm; function getDateofBirth(s) { let dob = /(?:Date\sof\sBirth:\s)?:(\w+\s\d{1,2}\,\s\d{4})/; return s.match(dob)[1] } function replaceDOB(s) { s = s.replace(dobReplacement, "$1"+getDateofBirth+"$2"); return s; } function run(argv) { return cleanup(argv[0]); } mill take a look when I get home. I’ll also write it to be a little bit more flexible. Again, JavaScript is not a strength of mine, I use python and golang much more. I’ll do what I can
Terminal Posted January 11, 2020 Posted January 11, 2020 @slyfox Here is working replacement of DOB To better help you, what all should this script do? Should one workflow, change pronouns, dob, and name? Or do you want to trigger all of these individually? Can you explain your ideal workflow? As it is completely possible, but without understanding what you are fully trying to accomplish, it is harder to create what you need. #!/usr/bin/osascript -l JavaScript var dobReplacement = /(\W|^)DOB(\W|$)/gm; function getDateofBirth(s) { let dob = /(?:Date\sof\sBirth:\s)(\w+\s\d{1,2}\,\s\d{4})/; return s.match(dob)[1] } function replaceDOB(s) { s = s.replace(dobReplacement, "$1"+getDateofBirth(s)+"$2"); return s; } function run(argv) { return replaceDOB(argv[0]); }
slyfox Posted January 11, 2020 Author Posted January 11, 2020 (edited) I am trying to replace a Keyboard Maestro workflow with Alfred workflow. 1. CMD+A to select text 2. Copy to Clipboard 3. Execute Find & replace 4. Paste back the results. For step 3 my report will have this info at the top: ### Client Info - Clinic: Advanced Healthcare - Name: Mr. John Smith - Date of Birth: January 10, 1980 - Date of Loss: January 10, 2019 - Date of Assessment: January 10, 2020 I need to find and set variables: firstName = John lastName = Smith dob = January 10, 1980 dol = January 10, 2019 Then replace (content of the report): NN with firstName --> ([M][r-s]\.\s)(\w*\s)(\w*) - group 2 XX with lastName --> ([M][r-s]\.\s)(\w*\s)(\w*) - group 3 DOB with dob --> Date\s\of\s\Birth:\s(\w+\s\d{1,2}\,\s\d{4}) DOL with dol --> Date\s\of\s\Loss:\s(\w+ \d{1,2},\s\d{4}) Edited January 11, 2020 by slyfox
Terminal Posted January 11, 2020 Posted January 11, 2020 2 hours ago, slyfox said: I am trying to replace a Keyboard Maestro workflow with Alfred workflow. 1. CMD+A to select text 2. Copy to Clipboard 3. Execute Find & replace 4. Paste back the results. For step 3 my report will have this info at the top: ### Client Info - Clinic: Advanced Healthcare - Name: Mr. John Smith - Date of Birth: January 10, 1980 - Date of Loss: January 10, 2019 - Date of Assessment: January 10, 2020 I need to find and set variables: firstName = John lastName = Smith dob = January 10, 1980 dol = January 10, 2019 Then replace (content of the report): NN with firstName --> ([M][r-s]\.\s)(\w*\s)(\w*) - group 2 XX with lastName --> ([M][r-s]\.\s)(\w*\s)(\w*) - group 3 DOB with dob --> Date\s\of\s\Birth:\s(\w+\s\d{1,2}\,\s\d{4}) DOL with dol --> Date\s\of\s\Loss:\s(\w+ \d{1,2},\s\d{4}) This definitely can be cleaned up better. But test this out. A video in action https://gifyu.com/image/mVZs #!/usr/bin/osascript -l JavaScript var firstNameReplacement = /(\W|^)NN(\W|$)/gm; var lastNameReplacement = /(\W|^)XX(\W|$)/gm; var dobReplacement = /(\W|^)DOB(\W|$)/gm; var dolReplacement = /(\W|^)DOL(\W|$)/gm; function getName(s) { let pattern = /Name:\s(?:[M][r-s]\.\s)(\w*)\s(\w*)/; return s.match(pattern) } function replaceName(s) { s = s.replace(firstNameReplacement, "$1"+getName(s)[1]+"$2"); s = s.replace(lastNameReplacement, "$1"+getName(s)[2]+"$2"); return s; } function getDateofBirth(s) { let dob = /(?:Date\sof\sBirth:\s)(\w+\s\d{1,2}\,\s\d{4})/; return s.match(dob)[1] } function replaceDOB(s) { s = s.replace(dobReplacement, "$1"+getDateofBirth(s)+"$2"); return s; } function getDateofLoss(s) { let dol = /(?:Date\sof\sLoss:\s)(\w+\s\d{1,2}\,\s\d{4})/; return s.match(dol)[1] } function replaceDOL(s) { s = s.replace(dolReplacement, "$1"+getDateofLoss(s)+"$2"); return s; } function run(argv) { var content = argv[0]; content = replaceName(content); content = replaceDOB(content); content = replaceDOL(content); return content }
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now