Script to move the last word of a string to the beginning Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
menteith
Posts: 51
Joined: 04 Feb 2016, 12:22

Script to move the last word of a string to the beginning

27 Jun 2016, 08:24

Hi all!

What I would like to achieve is to create a script that would move the last word in a string to the beginning of it. Additionally, a comma and a space should be added to the last word. Here is an example of this:

Code: Select all

John Smith 
John Anderson Smith 
John A. Smith 
J.A. Smith
The result should be:

Code: Select all

Smith, John 
Smith, John Anderson 
Smith, John A. 
Smith, J.A.
To do this, I created this regex :

Code: Select all

RegExReplace(string, "^(.+?)\s+(\S+)$", "$2, $1")
This is the only part I could dealt with.

But how about names starting with with e.g. 'van' etc? They should be changed as follows:

Code: Select all

John van Smith -> van Smith, John
In other words, if a certain string is found (case sensitive) all is after it should go at the start. Some of these string are as follows.

participle := "della,von dem,van der,Van der,van de,de,De,der,van,Van,’t"

And last thing: some people have after their surname strings like: Jr, Sr, II, III, IV.

Code: Select all

Jim E. Deer, Jr.

Joe L. Smith Sr

Bob van der Sloot IV
They should be changed to:

Code: Select all

Deer, Jim E., Jr.
Smith, Joe L., Sr
van der Sloot, Bob, IV
I would make use of same help. Thanks in advance!
An ordinary user who needs some help with developing own programs for his own use.
kon
Posts: 1756
Joined: 29 Sep 2013, 17:11

Re: Script to move the last word of a string to the beginning

27 Jun 2016, 11:47

Here's a first attempt. It seems to be working for the examples provided.

Code: Select all

Test =
(Join`r`n
John Smith 
John Anderson Smith 
John A. Smith 
J.A. Smith
John A. der Smith 
John van Smith
Jim E. Deer, Jr.
Joe L. Smith Sr
Bob van der Sloot IV
)

MsgBox, % Test2 := RegExReplace(RegExReplace(Test, "
(Join`r`n
    mx)
    ^([\w\h\.]+?)
    \h?((\b(della|von\hdem|van\hder|Van\hder|van\hde|de|De|der|van|Van|’t)\b\h)?
    \b[\w]+\b)
    ([,\h]*?(Jr\.?|Sr\.?|II|III|IV))?
    \h?$
)", "$2, $1, $6")
, "m)[,\h]+$")
https://regex101.com/r/zJ8mV3/1
User avatar
menteith
Posts: 51
Joined: 04 Feb 2016, 12:22

Re: Script to move the last word of a string to the beginning

28 Jun 2016, 05:01

[quote="kon"]Here's a first attempt. It seems to be working for the examples provided.

Code: Select all

[/quote]

Thank you, it does the trick. Would it be to much if I kindly ask you to change the code to use standard AHK procedure and RegEx only if needed? I think it would be faster and I would learn from your code as well. Thanks in advance!
An ordinary user who needs some help with developing own programs for his own use.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Script to move the last word of a string to the beginning  Topic is solved

28 Jun 2016, 07:03

Swapping the word order is as simple as: RegexReplace(name, "(^.*)\s+(\w+$)", "$2, $1")

Code: Select all

names := ["John Smith", "John Anderson Smith", "John A. Smith", "J.A. Smith"]

out := ""
Loop % names.length() {
	name := names[A_Index]
	out .= (name " = " RegexReplace(name, "(^.*)\s+([\w-]+$)", "$2, $1") "`n")
}

msgbox % out
clipboard := out
John Smith = Smith, John
John Anderson Smith = Smith, John Anderson
John Anderson-Smith = Anderson-Smith, John
John A. Smith = Smith, John A.
J.A. Smith = Smith, J.A.

[Edit] Updated to support hyphenated surnames, eg John Anderson-Smith

However, for the suffixes (Jr, II, III etc), I dunno. Do you have an exhaustive list?
User avatar
menteith
Posts: 51
Joined: 04 Feb 2016, 12:22

Re: Script to move the last word of a string to the beginning

28 Jun 2016, 07:36

evilC wrote:Swapping the word order is as simple as:
Thanks for this. What about "von, van, della" and other that should be added before surname?

For example:

Jane della Smith -> della Smith, Jane?

And there is no need to use "`n" because my strings will be just name and a surname (only one person at once).
evilC wrote:However, for the suffixes (Jr, II, III etc), I dunno. Do you have an exhaustive list?
Thanks for this. As to the suffixies, I think that "II, III, IV, Jr, Sr" will be enought, and some other suffixies could be added later.

I hope I more clear now:)
An ordinary user who needs some help with developing own programs for his own use.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Script to move the last word of a string to the beginning

28 Jun 2016, 13:47

I am no regex expert, this is probably the most complex regex I have ever written, but here is my solution:

RegexReplace(name, "Ui)^(.*)[^\w]+([\w-\.]+)([\s\,]+)?(\s*[^\w]?\s*(jr|sr|iv)[^\w]?)?$", "$2, $1$4")
I only added jr, sr and iv but you can easily patch in any suffixes you like.

Capture pattern $1 is the first name.
$2 is all other names that aren't part of a suffix.
$4 is the suffix, with optional punctuation before or after (eg "sr", "jr.", ",jr" or ", jr")

Test code:

Code: Select all

#SingleInstance force

names := ["John Smith", "John Anderson Smith", "John A. Smith", "J.A. Smith"
	, "Jim E. Deer, Jr.", "Jim E Deer, Jr", "Joe L. Smith Sr", "Bob van der Sloot IV"]
 
out := ""
Loop % names.length() {
	name := names[A_Index]
	out .= (name " = " RegexReplace(name, "Ui)^(.*)[^\w]+([\w-\.]+)([\s\,]+)?(\s*[^\w]?\s*(jr|sr|iv)[^\w]?)?$", "$2, $1$4") "`n")
}
 
msgbox % out
clipboard := out
John Smith = Smith, John
John Anderson Smith = Smith, John Anderson
John A. Smith = Smith, John A
J.A. Smith = Smith, J.A
Jim E. Deer, Jr. = Deer, Jim E, Jr.
Jim E Deer, Jr = Deer, Jim E, Jr
Joe L. Smith Sr = Smith, Joe L Sr
Bob van der Sloot IV = Sloot, Bob van der IV

Oh and the `n is not part of the regex, it is merely to place each result on it's own line in the msgbox.

[Edit: Update to better handle punctuation or whitespace as part of the suffix]
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Script to move the last word of a string to the beginning

28 Jun 2016, 14:19

Hmm, I think that regex was over-complicated. This may be better, and it's a whole lot more understandable

Code: Select all

#SingleInstance force

names := ["John Smith", "John Anderson Smith", "John A. Smith", "J.A. Smith"
	, "Jim E. Deer, Jr.", "Jim E Deer, Jr", "Joe L. Smith Sr", "Bob van der Sloot IV"]
 
forenames := ".*"	; Anything
surname := "[\w]+"	; One or more word characters
suffixes := "[^\w]+(jr|sr|iv)+[^\w]*"	; One or more punctuation / whitespace followed by valid suffix followed by optional punctuation / whitespace
regex := "Ui)^(" forenames ") (" surname ")(" suffixes ")?$"	; Forenames, Surname, optional suffixes

out := ""
Loop % names.length() {
	name := names[A_Index]
	out .= (name " = " RegexReplace(name, regex, "$2, $1$3") "`n")
}
 
msgbox % out
clipboard := out
John Smith = Smith, John
John Anderson Smith = Smith, John Anderson
John A. Smith = Smith, John A.
J.A. Smith = Smith, J.A.
Jim E. Deer, Jr. = Deer, Jim E., Jr.
Jim E Deer, Jr = Deer, Jim E, Jr
Joe L. Smith Sr = Smith, Joe L. Sr
Bob van der Sloot IV = Sloot, Bob van der IV
sadasada
Posts: 9
Joined: 20 Aug 2020, 03:46

Re: Script to move the last word of a string to the beginning

20 Aug 2020, 03:52

Perfect regex.
Its very late reply to post since i recently joined forums. But i need help with this script. It is unable to work correctly with German words like: if i want to apply it on: Christian W. Günther, its output is nther, Christian W. G.,. It is skipping German character. Any help in this regard?

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: RandomBoy, scriptor2016 and 360 guests