I'm attempting to replace a character within a string, which in this case is a digit, with another digit that has been incremented by 1, and then adding it back to the original string and replacing the previous digit character.
In the below snippet, sams2 should become sams3 after this code has executed
However, I keep receiving the error, Unable to index into an object of type System.String. Is it not possible to replace characters through indexing? Is there a better methodology for something like this?
$SAMAccountName = "sams2"
$lastChar = $SAMAccountName.Length - 1
[int]$intNum = [convert]::ToInt32($SAMAccountName[$lastChar])
$convertedChar = [convert]::ToString($intNum + 1)
$SAMAccountName[$lastChar] = $convertedChar
This would only work if the incremental number is one digit.
$SAMAccountName = "sams2"
$partOne = $SAMAccountName.SubString(0, $SAMAccountName.Length - 1)
$partTwo = [int]$SAMAccountName.SubString($SAMAccountName.Length - 1, 1) + 1
$SAMAccountName = "$partOne$partTwo"
Ok, this is a two step process. First we get the number off the end, then we replace that number in the string.
'sams2' |%{
$Int = 1+ ($_ -replace "^.*?(\d+)$",'$1')
$_ -replace "\d+$",$Int
}
Maybe try regular expressions and groups and then be able to handle multi-digits for free...
$SAMAccountName = "sam2"
# use regex101.com for help with regular expressions
if ($SAMAccountName -match "(.*?)(\d+)")
{
# uncomment for debugging
#$Matches
$newSAMAccountName = $Matches[1] + (([int]$Matches[2])+1)
$newSAMAccountName
}
There are a couple of things to note in your code:
Strings are immutable. New instance of string is created every time some change is made.
Use StringBuilder to manipulate individual chars.
Make sure you have compatible types. String is not char.
Take a look at following snippet:
$SAMAccountName = "sams2"
$sb = [System.Text.StringBuilder]$SAMAccountName
$lastChar = $SAMAccountName.Length - 1
[int]$intNum = [convert]::ToInt32($SAMAccountName[$lastChar])
$covertedChar = [convert]::ToChar($intNum + 1)
$sb[$lastChar] = $covertedChar
[string]$sb
You can also use another metod, like following one:
$SAMAccountName = "sams2"
$SAMAccountName.Substring(0, $SAMAccountName.Length-1)+([int]$SAMAccountName.Substring($SAMAccountName.Length-1, 1)+1)
Related
Input
str = 'test1,test2,test3,'
Ouput
str = 'test1,test2,test3'
Requirement to strip the last occurence of ','
Just use rstrip().
result = your_string.rstrip(',')
str = 'test1,test2,test3,'
str[:-1] # 'test1,test2,test3'
The question is very old but tries to give the better answer
str = 'test1,test2,test3,'
It will check the last character, if the last character is a comma it will remove otherwise will return the original string.
result = str[:-1] if str[-1]==',' else str
Though it is little bit over work for something like that. I think this statement will help you.
str = 'test1,test2,test3,'
result = ','.join([s for s in str.split(',') if s]) # 'test1,test2,test3'
If you have to remove the last comma (also as the last character?) you can do this via the function removesuffix()
Here is an example:
>>>'hello,'.removesuffix(',')
'hello'
Actually we have to consider the worst case also.
The worst case is,
str= 'test1,test2,test3, ,,,, '
for above code, please use following code,
result = ','.join([s.strip() for s in str.split(',') if s.strip()!=''])
It will work/remove the prefix 'comma' also. For example,
str= ' , ,test1,test2,test3, ,,,, '
I need to replace all content after a specific character in groovy with the value of a parameter,
my string is :
env.APP_VERSION="1.9"
And I would like to replace everything after the = sign with the value of a certain parameter let's call it $PARAM.
I was able to trim everything after the = sign,
but not replace it...
result = result.substring(0, result.indexOf('APP_VERSION='));
any help would be appreciated.
One of possible solutions is, indeed, to use regex. It should include:
(?<==) - A positive lookbehind for =.
.* - Match all chars (up to the end).
So the script can look like below:
src = 'env.APP_VERSION="1.9"'
PARAM = '"xyz"'
res = src.replaceFirst(/(?<==).*/, PARAM)
Another solution is to split the string on = and "mount" the result string
from:
The first string from split result.
= char.
Your replacement string.
This time the processing part of the script should be:
spl = src.split('=')
res = spl[0] + '=' + PARAM
Without knowing about your original intentions you have 2 options:
1) Do not reinvent the wheel and use GString magic:
String ver = '1.9'
String result = "env.APP_VERSION=\"$ver\""
2) use some regex:
result = result.replaceFirst( /APP_VERSION="[^"]+"/, 'APP_VERSION="something"' )
I have an Array where some drive data from WMI are captured:
$drivedata = $Drives | select #{Name="Kapazität(GB)";Expression={$_.Kapazität}}
The Array has these values (2 drives):
#{Kapazität(GB)=1.500} #{Kapazität(GB)=1.500}
and just want to convert the 1.500 into a number 1500
I tried different suggestions I found here, but couldn't get it working:
-Replace ".","" and [int] doesn't work.
I am not sure if regex would be correct and how to do this.
Simply casting the string as an int won't work reliably. You need to convert it to an int32. For this you can use the .NET convert class and its ToInt32 method. The method requires a string ($strNum) as the main input, and the base number (10) for the number system to convert to. This is because you can not only convert to the decimal system (the 10 base number), but also to, for example, the binary system (base 2).
Give this method a try:
[string]$strNum = "1.500"
[int]$intNum = [convert]::ToInt32($strNum, 10)
$intNum
Simply divide the Variable containing Numbers as a string by 1. PowerShell automatically convert the result to an integer.
$a = 15; $b = 2; $a + $b --> 152
But if you divide it before:
$a/1 + $b/1 --> 17
Since this topic never received a verified solution, I can offer a simple solution to the two issues I see you asked solutions for.
Replacing the "." character when value is a string
The string class offers a replace method for the string object you want to update:
Example:
$myString = $myString.replace(".","")
Converting the string value to an integer
The system.int32 class (or simply [int] in powershell) has a method available called "TryParse" which will not only pass back a boolean indicating whether the string is an integer, but will also return the value of the integer into an existing variable by reference if it returns true.
Example:
[string]$convertedInt = "1500"
[int]$returnedInt = 0
[bool]$result = [int]::TryParse($convertedInt, [ref]$returnedInt)
I hope this addresses the issue you initially brought up in your question.
I demonstrate how to receive a string, for example "-484876800000" and tryparse the string to make sure it can be assigned to a long. I calculate the Date from universaltime and return a string. When you convert a string to a number, you must decide the numeric type and precision and test if the string data can be parse, otherwise, it will throw and error.
function universalToDate
{
param (
$paramValue
)
$retVal=""
if ($paramValue)
{
$epoch=[datetime]'1/1/1970'
[long]$returnedLong = 0
[bool]$result = [long]::TryParse($paramValue,[ref]$returnedLong)
if ($result -eq 1)
{
$val=$returnedLong/1000.0
$retVal=$epoch.AddSeconds($val).ToString("yyyy-MM-dd")
}
}
else
{
$retVal=$null
}
return($retVal)
}
Replace all but the digits in the string like so:
$messyString = "Get the integer from this string: -1.500 !!"
[int]$myInt = $messyString -replace '\D', ''
$myInt
# PS > 1500
The regex \D will match everything except digits and remove them from your string.
This will work fine for your example.
It seems the issue is in "-f ($_.Partition.Size/1GB)}}" If you want the value in MB then change the 1GB to 1MB.
I have strings of the form:
cake!apple!
apple!
cake!juice!apple!cake!
juice!cake!
In other words, these strings are composed of the three sub-strings "cake!", "apple!" and "juice!".
I need to validate these strings. The way to do this with a regular expression is thus:
/^(apple!|juice!|cake!)*$/
But Lua's patterns don't have the | operator, so it seemingly can't be done this way.
How can I validate my strings in Lua?
(I don't care about the contents of the strings: I only care about whether they conform (validate) or not.)
I know to write the code to do this but I can't think of a short way to do this. I'm looking for a short solution. I wonder if there's an elegant solution that I'm not aware of. Any ideas?
if str:gsub("%w+!", {["apple!"]="", ["juice!"]="", ["cake!"]=""}) == "" then
--do something
end
This solution uses a table as the second parameter to string.gsub. Since the patterns all match %w+, the table will validate for second time, only the real three patterns are replaced with an empty string. If after all the replacement, the string becomes empty, then the match succeeds.
Using a helper table variable can make it more clear:
local t = {["apple!"]="", ["juice!"]="", ["cake!"]=""}
if str:gsub("%w+!", t) == "" then
--do something
end
If there is a character that will never be in your string, for instance, the character "\1"(ASCII 1) is unlikely in a normal string, you can use this:
local str = "cake!juice!apple!cake!"
if str:gsub("apple!","\1"):gsub("juice!","\1"):gsub("cake!","\1"):gsub("\1","") == "" then
--do something
end
By replacing every match of the patterns to "\1", and finally replace "\1" to an empty string, the correct match would be an empty string in the end.
It has flaws(sometimes it's impossible to find a character that is never in the string), but I think it works in many situations.
The following seems to work for (the included) quick tests.
local strs = {
"cake!apple!",
"bad",
"apple!",
"apple!bad",
" apple!bad",
"cake!juice!apple!cake!",
"cake!juice! apple!cake!",
"cake!juice!badapple!cake!",
"juice!cake!",
"badjuice!cake!",
}
local legalwords = {
["cake!"] = true,
["apple!"] = true,
["juice!"] = true,
}
local function str_valid(str)
local newpos = 1
for pos, m in str:gmatch("()([^!]+!)") do
if not legalwords[m] then
return
end
newpos = pos + m:len()
end
if newpos ~= (str:len() + 1) then
return nil
end
return true
end
for _, str in ipairs(strs) do
if str_valid(str) then
print("Match: "..str)
else
print("Did not match: "..str)
end
end
Just to provide another answer, you can do this easily with lpeg's re module:
re = require 're'
local testdata =
{
"cake!apple!",
"apple!",
"cake!juice!apple!cake!",
"cake!juice!badbeef!apple!cake!",
"juice!cake!",
"badfood",
}
for _, each in ipairs(testdata) do
print(re.match(each, "('cake!' / 'apple!' / 'juice!')*") == #each + 1)
end
This outputs:
true
true
true
false
true
false
This looks almost like your regex pattern above minus the ^ $ of course since lpeg matching is always anchored.
Lua patterns are not a replacement for regular expressions, and cannot represent this sort of pattern. In this case, you just need to repeatedly make sure the front of the string matches one of your words and then pop it off, but you probably already knew that.
Something like:
local words = {cake=1,apple=2,juice=3}
local totals = {}
local matches = 0
local invalid = 0
string.gsub("cake!","(%a+)!",
function(word)
local index = words[word]
if index then
matches = matches + 1
totals[index] = totals[index] + 1
else
invalid = invalid + 1
end
end
)
if matches > 0 and invalid == 0 then
-- Do stuff
end
This will pass each word to the supplied function where you can validate each one.
I dont know if it'll help you to get by you problem. But using string.find() i could use "or". look:
str="juice!"
print(string.find(str, "cake!" or "teste"))
best regards
I'm trying to find the locations where a substring occurs in a cell array in MATLAB. The code below works, but is rather ugly. It seems to me there should be an easier solution.
cellArray = [{'these'} 'are' 'some' 'nicewords' 'and' 'some' 'morewords'];
wordPlaces = cellfun(#length,strfind(cellArray,'words'));
wordPlaces = find(wordPlaces); % Word places is the locations.
cellArray(wordPlaces);
This is similar to, but not the same as this and this.
The thing to do is to encapsulate this idea as a function. Either inline:
substrmatch = #(x,y) ~cellfun(#isempty,strfind(y,x))
findmatching = #(x,y) y(substrmatch(x,y))
Or contained in two m-files:
function idx = substrmatch(word,cellarray)
idx = ~cellfun(#isempty,strfind(word,cellarray))
and
function newcell = findmatching(word,oldcell)
newcell = oldcell(substrmatch(word,oldcell))
So now you can just type
>> findmatching('words',cellArray)
ans =
'nicewords' 'morewords'
I don't know if you would consider it a simpler solution than yours, but regular expressions are a very good general-purpose utility I often use for searching strings. One way to extract the cells from cellArray that contains words with 'words' in them is as follows:
>> matches = regexp(cellArray,'^.*words.*$','match'); %# Extract the matches
>> matches = [matches{:}] %# Remove empty cells
matches =
'nicewords' 'morewords'