How to subtract from numbers following a string in VIM? - vim

I am trying to subtract from numbers following a string in VIM, for example this (searched) input:
CustomModelData: 1
And my preferred (replaced) output:
CustomModelData: -2147483647
The number that I am trying to subtract from the numbers is 2147483648. I tried using this in VIM, but it doesn't work since there is a string in the expression, I want to keep the string while also subtracting from the number that follows:
:%s/CustomModelData: \d\+/\=/CustomModelData: submatch(0)-2147483648/g

You can use following minor adjustment to have the match start at the number so the replacement only sees the number to adjust
%s/\vCustomModelData: \zs\d+/\=submatch(0)-2147483648/g
\zs anything, sets start of match

If each number is on a separate line of the file, then you can match relevant lines and use the Ctrl+X subtraction operator on them:
:g/CustomModelData:/ norm 2147483648^X
(For the ^X, type Ctrl+X.)

Related

Format in Python

I have a list of values as follows:
no column
1. 111-222-11
2. 112-333-12
3. 113-444-13
I want to format the value from 111-222-11 to 111-222-011 and format the other values similarly. Here is my code snippet in Python 3, which I am trying to use for that:
‘{:03}-{:06}-{:03}.format(column)
I hope that you can help.
Assuming that column is a variable that can be assigned string values 111-222-11, 112-333-12, 113-444-13 and so on, which you want to change to 111-222-011, 112-333-012, 113-444-013 and so on, it appears that you tried to use a combination of slice notation and format method to achieve this.
Slice notation
Slice notation, when applied to a string, treats it as a list-like object consisting of characters. The positional index of a character from the beginning of the string starts from zero. The positional index of a character from the end of the string starts with -1. The first colon : separates the beginning and the end of a slice. The end of the slice is not included into it, unlike its beginning. You indicate slices as you would indicate indexes of items in a list by using square brackets:
'111-222-11'[0:8]
would return
'111-222-'
Usually, the indexes of the first and the last characters of the string are skipped and implied by the colon.
Knowing the exact position where you need to add a leading zero before the last two digits of a string assigned to column, you could do it just with slice notation:
column[:8] + '0' + column[-2:]
format method
The format method is a string formatting method. So, you want to use single quotes or double quotes around your strings to indicate them when applying that method to them:
'your output string here'.format('your input string here')
The numbers in the curly brackets are not slices. They are placeholders, where the strings, which are passed to the format method, are inserted. So, combining slices and format method, you could add a leading zero before the last two digits of a column string like this:
'{0}0{1}'.format(column[:8], column[-2:])
Making more slices is not necessary because there is only one place where you want to insert a character.
split method
An alternative to slicing would be using split method to split the string by a delimiter. The split method returns a list of strings. You need to prefix it with * operator to unpack the arguments from the list before passing them to the format method. Otherwise, the whole list will be passed to the first placeholder.
'{0}-{1}-0{2}'.format(*column.split('-'))
It splits the string into a list treating - as the separator and puts each item into a new string, which adds 0 character before the last one.

Excel get substring from nth position up to the end of string

So How to get substring from nth position up to the end of string?
Input at cell A1 Name: Thomas B.
Expected output: Thomas B.
I know some way to do it but I wonder if there are other elegant ways than them? (some kind of =RIGHT(A1, -6)....)
=MID(A1, 6, 999999) //999999 looks not so good
=MID(A1, 6, LEN(A1) - 5) //must calculate 2 times, first get len, then get substring, seems too much works?
REPLACE
As Dominique already wrote:
'Why don't you just replace the first six characters by an empty string?'
=REPLACE(A1,1,6,"")
I've done some time measuring, but the difference is less than a second at 50000 records (for LEFT, MID, REPLACE & SUSTITUTE). So I'm afraid ELEGANCE is all you're going to get.
A Small Study
I created this study due to the fact that when you say from the n-th character, your n-th character is 7 (your MID-s are wrong), but you want to remove the first n-1 (6) characters. So depending on how you formulate your question, you might have a different approach in RIGHT or MID, and you will remember REPLACE and SUBSTITUTE or you may not.
Small Study Formulas for A1 (*) and B1 (#, ?, *)
Get String From N-th Character to the End, e.g. 7
=RIGHT(A1,LEN(A1)-(B1-1))
=RIGHT(A1,LEN(A1)-B1+1)
=RIGHT(A1,LEN(A1)-6)
=MID(A1,B1,LEN(A1)-(B1-1))
=MID(A1,B1,LEN(A1)-B1+1)
=MID(A1,B1,LEN(A1))
=MID(A1,7,LEN(A1)-6)
=MID(A1,7,LEN(A1))
Remove N First Characters of a String, e.g. 6
=RIGHT(A1,LEN(A1)-B1)
=RIGHT(A1,LEN(A1)-6)
=MID(A1,B1+1,LEN(A1)-B1)
=MID(A1,B1+1,LEN(A1))
=MID(A1,7,LEN(A1)-6)
=MID(A1,7,LEN(A1))
Get String After a Character e.g. " "
=RIGHT(A1,LEN(A1)-(FIND(B1,A1)))
=RIGHT(A1,LEN(A1)-(FIND(" ",A1)))
=MID(A1,FIND(B1,A1)+1,LEN(A1)-FIND(B1,A1))
=MID(A1,FIND(B1,A1)+1,LEN(A1))
=MID(A1,FIND(" ",A1)+1,LEN(A1)-FIND(" ",A1))
=MID(A1,FIND(" ",A1)+1,LEN(A1))
Get String After a String e.g. ": "
=RIGHT(A1,LEN(A1)-(FIND(B1,A1)+LEN(B1))+1)
=RIGHT(A1,LEN(A1)-FIND(B1,A1)-LEN(B1)+1)
=RIGHT(A1,LEN(A1)-FIND(": ",A1)-LEN(": ")+1)
=MID(A1,FIND(B1,A1)+LEN(B1),LEN(A1)-(FIND(B1,A1)+LEN(B1))+1)
=MID(A1,FIND(B1,A1)+LEN(B1),LEN(A1)-FIND(B1,A1)-LEN(B1)+1)
=MID(A1,FIND(B1,A1)+LEN(B1),LEN(A1))
=MID(A1,FIND(": ",A1)+LEN(": "),LEN(A1)-FIND(": ",A1)-LEN(": ")+1)
=MID(A1,FIND(": ",A1)+LEN(": "),LEN(A1))
Back to Remove N First Characters of a String, e.g. 6
=SUBSTITUTE(A1,LEFT(A1,6),"",1)
=REPLACE(A1,1,6,"")
Well, both of your methods already work, but you could also use this one:
=RIGHT(A1,LEN(A1)-6)
(you nearly had this one in your own question)
or this one:
=TRIM(MID(A1,FIND(":",A1)+1,100))
(the FIND() function returns the numeric position of a search string, so is great for doing dynamic substrings)
Why don't you just replace the first six characters by an empty string?
=SUBSTITUTE(A1;LEFT(A1;6);"";1)
Another possibility is that you create a constant with the value 2^31-1 (=2147483647), which is the maximum signed integer value on 32-bit systems, and you give it a nice name, like MaxInt, then your first formula will be efficient and nice looking, too:
=MID(A1, 6, MaxInt)
You can add the Name with Ctrl+F3. If you are interested in fast calculations, giving it as 2147483647 rather than 2^31-1 may have some (very little) advantage.

Remove all text and characters except some

I have here some text strings
"16cg-301 -request","16cg-3368 - for review","16cg-3684 - for process"
what i would like to do is to remove all the text and characters except the number and the letters "cg" and - which is within the reference code.
If the string you want to extract is always before the first space in the full string then you can use SEARCH and LEFT to extract your reference code:
=LEFT(A1,SEARCH(" ",A1)-1)
This formula would take 16cg-3368 from 16cg-3368 - for review.
I suggest using something like suggested here
How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops
With a replace regex similar to this
[^\dcg]*
or a match regex like this
^([0-9cg- ]+).*
else you could also work with a strange formule similar to this
=CONCATENATE(IF(NOT(ISERROR(SEARCH(MID(A2;1;1);"01234567890cg-")>0));MID(A2;1;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;2;1);"01234567890cg-")>0));MID(A2;2;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;3;1);"01234567890cg-")>0));MID(A2;3;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;4;1);"01234567890cg-")>0));MID(A2;4;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;5;1);"01234567890cg-")>0));MID(A2;5;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;6;1);"01234567890cg-")>0));MID(A2;6;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;7;1);"01234567890cg-")>0));MID(A2;7;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;8;1);"01234567890cg-")>0));MID(A2;8;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;9;1);"01234567890cg-")>0));MID(A2;9;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;10;1);"01234567890cg-")>0));MID(A2;10;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;11;1);"01234567890cg-")>0));MID(A2;11;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;12;1);"01234567890cg-")>0));MID(A2;12;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;13;1);"01234567890cg-")>0));MID(A2;13;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;14;1);"01234567890cg-")>0));MID(A2;14;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;15;1);"01234567890cg-")>0));MID(A2;15;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;16;1);"01234567890cg-")>0));MID(A2;16;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;17;1);"01234567890cg-")>0));MID(A2;17;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;18;1);"01234567890cg-")>0));MID(A2;18;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;19;1);"01234567890cg-")>0));MID(A2;19;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;20;1);"01234567890cg-")>0));MID(A2;20;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;21;1);"01234567890cg-")>0));MID(A2;21;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;22;1);"01234567890cg-")>0));MID(A2;22;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;23;1);"01234567890cg-")>0));MID(A2;23;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;24;1);"01234567890cg-")>0));MID(A2;24;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;25;1);"01234567890cg-")>0));MID(A2;25;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;26;1);"01234567890cg-")>0));MID(A2;26;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;27;1);"01234567890cg-")>0));MID(A2;27;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;28;1);"01234567890cg-")>0));MID(A2;28;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;29;1);"01234567890cg-")>0));MID(A2;29;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;30;1);"01234567890cg-")>0));MID(A2;30;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;31;1);"01234567890cg-")>0));MID(A2;31;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;32;1);"01234567890cg-")>0));MID(A2;32;1);""))
only works by now for less than 33 signs.
problem here will be that you will get unexpected behavior like this:
123cg-123 - Process => 123cg-123-c
after rereading , I think you should try an other approach than described in the question ;-)
If you want to return everything up to and including the last digit, then try:
=LEFT(A1,LOOKUP(2,1/ISNUMBER(-MID(A1,seq,1)),seq))
seq is a named formula: Formula ► Define Name
Name: seq
Refers to: =ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,255,1))
seq returns an array of sequential numbers from 1 to 255.
mid(a1,seq,1)
returns an array consisting of the individual characters in the string in A1. The leading minus sign converts the digits from strings to numbers.
The lookup function will then return the position of the last digit

Excel copying part of a string between characters

Is there a way of returning part of a string between certain characters in excel? For example my string looks like this:
`switchrefid` = {switchrefid: }
I need to cut the part of the string between the ' (apostrophes) so it just returns switchrefid
I'm sure there must be a formula for this i just cant think of the one to use.
Thanks in advance.
As long as the ``` characters occur exactly twice in your data, you can do:
=LEFT(RIGHT(A1, LEN(A1)-FIND("`", A1)), FIND("`",RIGHT(A1, LEN(A1)-FIND("`", A1)))-1)
Although it is pretty horrible!
(Edit: this assumes your data is in A1, of course.)
Just two more options, if the word always starts at the second Character and ends just before the last you could simply use :
=MID(A1,2,LEN(A1)-2) ' Minus 2 for the 2 ticks
And the second option would be to substitute the tick with nothing like so:
=SUBSTITUTE(A1,"`","")
With the substitute is also supports a number of substitutes. So if you had `switchrefid`` for some reason and only want to get rid of 2 of the three ticks you could use:
=SUBSTITUTE(A1,"`","",2)
and this would return switchrefid`
although it would not work for ''switchrefid' as it would STILL return switchrefid' because it only removes the 1st 2 instances of the text to remove

How to obtain the n-th letter of the alphabet

Is there a short formula to get the n-th letter of the alphabet?
For example, if I give parameter 5 to the function, I would get the letter e.
There is a function CHAR which gives a character with the specified code:
CHAR(96 + 5)
will yield your "e".
But there is no direct way to get a character of the alphabet.
An alternate, although not as short as the CHAR function, is the CHOOSE function
=CHOOSE(5,"a","b","c","d","e","f","g","h","I","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z")
The index number '5' returns the fifth value in the list. The list could be an Excel range of data e.g. (A1:A26).
If the index number is outside the range, #VALUE! is returned
you could use an ascii function since every letter has a numeric value in ascii
Not sure what language your using... in T-SQL you can use an ASCII and CHAR functions:
PRINT CHAR(ASCII('A') + #i) -- where #i is your numeric value
There is also another simpler way: CHAR(CODE("A")+TRUNC(RAND()*26)).
This gives you the position of the letter in question (C3, for example) if it is capital or not.
=IF(AND(CODE(C3)>=65,CODE(C3)<=90),CODE(C3)-64,IF(AND(CODE(C3)>=97,CODE(C3)<=122),CODE(C3)-96,"Error"))

Resources