replace text maintain case

Post your working scripts, libraries and tools
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

replace text maintain case

21 Sep 2017, 15:26

Functions: JEE_StrCloneCase and JEE_StrReplaceMaintainCase

Code: Select all

;e.g.
;MsgBox, % JEE_StrCloneCase("yellow", "RED")
;MsgBox, % JEE_StrCloneCase("yellow", "Red")

JEE_StrCloneCase(vText, vCaseTemplate)
{
	local vCase,vOutput
	if (vCaseTemplate = "")
		return vText
	Loop, Parse, vCaseTemplate
	{
		vCase := (Format("{:L}", A_LoopField) == A_LoopField) ? "L" : "U"
		vOutput .= Format("{:" vCase "}", SubStr(vText, A_Index, 1))
	}
	vOutput .= Format("{:" vCase "}", SubStr(vText, StrLen(vCaseTemplate)+1))
	return vOutput
}

;==================================================

;e.g.
;MsgBox, % JEE_StrReplaceMaintainCase("ABC,Abc,abc,aBc,abC", "abc", "def")
;MsgBox, % JEE_StrReplaceMaintainCase("ABC,Abc,abc,aBc,abC", "abc", "defgh")

JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText:="", ByRef vCount:=0, vLimit:=-1)
{
	local oPos,oReplace,vDiff,vNeedle2,vOffset,vOutput,vPos,vSCS
	vCount := 0
	if (vNeedle = "") || (vNeedle = vReplaceText)
		return
	vSCS := A_StringCaseSense
	StringCaseSense, Off
	if (vReplaceText = "")
	{
		vOutput := StrReplace(vText, vNeedle, "", vCount, vLimit)
		StringCaseSense, % vSCS
		return vOutput
	}
	vPos := 1, oPos := {}, oReplace := {}
	Loop
	{
		if !(vLimit = -1) && (A_Index > vLimit)
			break
		vPos := InStr(vText, vNeedle, 0, vPos)
		if !vPos
			break
		oPos.Push(vPos)
		vNeedle2 := SubStr(vText, vPos, StrLen(vNeedle))
		oReplace.Push("" JEE_StrCloneCase(vReplaceText, vNeedle2))
		vPos += StrLen(vNeedle)
	}
	vOutput := StrReplace(vText, vNeedle, vReplaceText, vCount, vLimit)
	vDiff := StrLen(vReplaceText) - StrLen(vNeedle)
	Loop, % oPos.Length()
	{
		vOffset := (oPos[A_Index] + (A_Index-1)*vDiff - 1) * (A_IsUnicode?2:1)
		StrPut(oReplace[A_Index], &vOutput+vOffset, StrLen(vReplaceText))
	}
	StringCaseSense, % vSCS
	return vOutput
}
Example code:

Code: Select all

q::
vText := "ABC,Abc,abc,aBc,abC"
vNeedle := "abc"

vReplaceText := "def"
MsgBox, % JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText, vCount) " " vCount
vReplaceText := "def"
MsgBox, % JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText, vCount, 3) " " vCount

vReplaceText := "def"
MsgBox, % JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText)
vReplaceText := "defgh"
MsgBox, % JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText)
vReplaceText := "de"
MsgBox, % JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText)
vReplaceText := "d"
MsgBox, % JEE_StrReplaceMaintainCase(vText, vNeedle, vReplaceText)
return
Last edited by jeeswg on 21 Sep 2017, 16:26, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4664
Joined: 17 Jul 2016, 01:02
Contact:

Re: replace text maintain case

21 Sep 2017, 16:10

Seems very solid, thanks for sharing :thumbup:
Comment, it is nice that you use local, but keep in mind that it is a bit dangerous if you make a mistake, try this,

Code: Select all

oPos:="myFavouriteString"
MsgBox, % JEE_StrReplaceMaintainCase("ABC,Abc,abc,aBc,abC", "abc", "def")
msgbox % isObject(oPos)
We need force local :wave:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: replace text maintain case

21 Sep 2017, 16:23

Waitasec, what, how is that standard behaviour. I declared some variables local, so all other variables in the function that are not declared local or that are not parameters are assumed global!?

I don't even want to declare variables local, I only do it because people have asked me to. The only reason I'm adding in 'local' now, is to avoid clashes caused by #Warn.

Anyhow, thanks for reminding me, I use a checker that checks for variables that begin with 'A_' or 'v', but I should add 'o' also. [EDIT: Checker updated, I've added oPos,oReplace to the list of local variables.]

You should add your voice to that thread, I might do also.

I suppose for the function above, I could just use 'local' by itself, and that you only need to specify local with variable names, if you use 'global' or 'global MyVar' at some point in a function. Hmm, there is also 'static' to consider.

OK, so recently I've had a surprise with force expression, and now with local. What else? Have you checked my documentation extension tutorial ever, anything important missing from there? I.e. any surprising behaviour not mentioned. I will add mentions for those two points.

jeeswg's documentation extension tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=33596

Btw I'm looking for any scripts to list all of the variables in a function in relation to the local/global issue.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4664
Joined: 17 Jul 2016, 01:02
Contact:

Re: replace text maintain case

21 Sep 2017, 17:17

I declared some variables local, so all other variables in the function that are not declared local or that are not parameters are assumed global!?
Indeed this is the case, if you think about it, it is the only natural option. But it can be tedious and it is easy to make a mistake, that's why we would really benefit from local on its own, assuming local mode.
You should add your voice to that thread
I will if it goes to the second page 8-)
What else?
Who knows :lol:
Have you checked my documentation extension tutorial
I have browsed parts of it :thumbup:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: replace text maintain case

27 Sep 2017, 15:39

If you put something like global vMyDummyVar in a function, would that make all the other variables local?

Btw did you read through Wish List 2.0?
Wish List 2.0 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 13&t=36789
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4664
Joined: 17 Jul 2016, 01:02
Contact:

Re: replace text maintain case

27 Sep 2017, 16:12

No.
Not yet.
I'm on the phone hence the awkward responses. :angel:
jeeswg wrote:I was chuffed, I finally needed (and used) the function for the first time today.
:) :thumbup:
Last edited by Helgef on 12 Nov 2017, 14:07, edited 1 time in total.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: replace text maintain case

12 Nov 2017, 14:05

I was chuffed, I finally needed (and used) the function for the first time today.
I converted this: vPosX := oRect.x - vPosX
to this: vPosY := oRect.y - vPosY
Replacing x with y.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: replace text maintain case

11 Apr 2018, 03:46

- I've used this a second time. For HBITMAP:hBitmap to/from HICON:hIcon. Very satisfying to use it.
- It's also useful just for lazy replacements I've found. I.e. to replace 'OLDTEXT' with 'NEWTEXT', you feed it 'oldtext' and 'newtext'. So, it's the smart way to do *normal* text replacements, not just special cases.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
guest3456
Posts: 3329
Joined: 09 Oct 2013, 10:31

Re: replace text maintain case

11 Apr 2018, 09:03

jeeswg wrote:I don't even want to declare variables local, I only do it because people have asked me to.
don't do things just because people tell you do :)

jeeswg wrote:Waitasec, what, how is that standard behaviour. I declared some variables local, so all other variables in the function that are not declared local or that are not parameters are assumed global!?
yes, so don't do it. from the docs:
https://autohotkey.com/docs/Functions.htm wrote: Functions are assume-local by default.
even worse:
https://autohotkey.com/docs/Functions.htm wrote: Assume-global mode: If a function needs to access or create a large number of global variables, it can be defined to assume that all its variables are global (except its parameters) by making its first line either the word "global" or the declaration of a local variable.
so by merely declaring a local variable, as you have done, your function is now assume-global


Return to “Scripts and Functions”

Who is online

Users browsing this forum: ddt442, leosouza85 and 25 guests