Regex Replace variable number of ****** with predefined digits - c#

var panmaskednumber = "543034******0243"; Console.WriteLine(panmaskednumber.Count(x => x == '*'));
var pattern = "\\*";
var replace = "123456789";
Regex reg = new Regex(pattern);
var newnumber = reg.Replace(panmaskednumber, replace,panmaskednumber.Count(x => x == '*'));
Console.WriteLine(newnumber);
I'm trying to Replace * in var panmaskednumber(coming from DB with symmetric key).
Not liking to use the Contains approach in which I'm specifying number of * 6 / 7 with multiple If-elseif. Since those can vary between 6,7-9.
With my above approach it replaces for each char of -> * with var replace.
Any Linq approach if there is highly appreciated.
Result something: 5430341234567890243

You need to use a \*+ pattern that will match 1 or more asterisk symbols:
var panmaskednumber = "543034******0243";
var replace = "123456789";
var res = Regex.Replace(panmaskednumber, #"\*+", replace);
// res => 5430341234567890243
See the C# demo.
If the number of asterisks to be replaced depends on the replace length, you may pass the match value to the match evaluator and perform necessary manipulatons there:
var panmaskednumber = "543034*****0243";
var replace = "123";
var res = Regex.Replace(panmaskednumber, #"\*+", m =>
m.Value.Length <= replace.Length ?
replace.Substring(0, m.Value.Length) :
$"{replace}{m.Value.Substring(replace.Length)}"
);
Console.Write(res);
// "543034***0243" / "123456789" -> 543034 123 0243
// "543034*****0243" / "123" -> 543034 123** 0243
See antother C# demo

You can use a Regex, but you can achieve without. Lets go for a simpler solution. Try it online.
var panmaskednumber = "543034******0243";
var count = panmaskednumber.Count(x => x == '*');
var start = panmaskednumber.IndexOf('*');
var replace = "123456789";
// output 5430341234567890243 (543034 123456789 0243)
Console.WriteLine(panmaskednumber.Remove(start) // get head
+ replace // add replace
+ panmaskednumber.Substring(start + count)); // add tail
// output 5430341234560243 (543034 123456 0243) // get head
Console.WriteLine(panmaskednumber.Remove(start)
+ replace.Remove(count) // add replace with count respect
+ panmaskednumber.Substring(start + count)); // add tail
replace = "123";
// output 543034123***0243 (543034 123*** 0243) // get head
Console.WriteLine(panmaskednumber.Remove(start)
+ replace // add replace
+ new string('*', count - replace.Length) // fill with missing *
+ panmaskednumber.Substring(start + count)); // add tail
"I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail."
Law of instrument
Dont use Regex, if you don't have too. For this problem, C#.NET is enough. :)

Related

Remove part of a string between an start and end

Code first:
string myString = "<at>onePossibleName</at> some question here regarding <at>disPossibleName</at>"
// some code to handle myString and save it in myEditedString
Console.WriteLine(myEditedString);
//output now is: some question here regarding <at>disPossibleName</at>
I want to remove <at>onePossibleName</at> from myString. The string onePossibleName and disPossbileName could be any other string.
So far I am working with
string myEditedString = string.Join(" ", myString.Split(' ').Skip(1));
The problem here would be that if onePossibleName becomes one Possible Name.
Same goes for the try with myString.Remove(startIndex, count) - this is not the solution.
There will be different method depending on what you want, you can go with a IndexOf and a SubString, regex would be a solution too.
// SubString and IndexOf method
// Usefull if you don't care of the word in the at tag, and you want to remove the first at tag
if (myString.Contains("</at>"))
{
var myEditedString = myString.Substring(myString.IndexOf("</at>") + 5);
}
// Regex method
var stringToRemove = "onePossibleName";
var rgx = new Regex($"<at>{stringToRemove}</at>");
var myEditedString = rgx.Replace(myString, string.Empty, 1); // The 1 precise that only the first occurrence will be replaced
You could use this generic regular expression.
var myString = "<at>onePossibleName</at> some question here regarding <at>disPossibleName</at>";
var rg = new Regex(#"<at>(.*?)<\/at>");
var result = rg.Replace(myString, "").Trim();
This would remove all 'at' tags and the content between. The Trim() call is to remove any white space at the beginning/end of the string after the replacement.
string myString = "<at>onePossibleName</at> some question here regarding <at>disPossibleName</at>"
int sFrom = myString.IndexOf("<at>") + "<at>".Length;
int sTo = myString.IndexOf("</at>");
string myEditedString = myString.SubString(sFrom, sFrom - sTo);
Console.WriteLine(myEditedString);
//output now is: some question here regarding <at>disPossibleName</at>

How to convert quarter which is provided as "FY18 Q1" to produce "2018.4" in C# using REGEX?

The below code works fine. But, I want to obtain this via Regex.
private decimal GetQuarter(string quarter)
{
var unformattedQuarter = "20" + quarter[2] + quarter[3] + "." + quarter[6];
return Convert.ToDecimal(unformattedQuarter);
}
Input
FY18 Q4
FY19 Q1
FY19 Q2
Output
2018.4
2019.1
2019.2
You can use the pattern
FY(\d{2}) Q(\d)
And replace matches with
20$1.$2
Example
var input = #"FY18 Q4\r\nFY19 Q1\r\nFY19 Q2";
var pattern = #"FY(\d{2}) Q(\d)";
var replacement = "20$1.$2";
Console.WriteLine(Regex.Replace(input, pattern, replacement));
Output
2018.4
2019.1
2019.2
Full Demo Here
Explanation
Note : Adding 20 seems a little problematic, and should be used with caution
Using the following code, you can extract the first and second occurrences of the numbers from the string into a list and then concatenate them:
string n = "FY18 Q1";
Regex digits = new Regex(#"[\d]+");
var list = digits.Matches(n);
var finalValue = "20" + list [0] + "." + list [1];

Remove a value from comma separated string in C#

I have done something like:
var a = "77,82,83";
foreach (var group in a.Split(','))
{
a = group.Replace("83", string.Empty);
}
If i want to remove 83 but override last updated value and got output empty or remove value from that i passed to replace.
e.g var a = 77,82,83
want output like 77,82
Edit:
"83" can be in any position.
If you want output as string you don't need to Split. Just get the LastIndexOf the , character and perform Substring on the variable:
var a = "77,82,83";
var newString = a.Substring(0, a.LastIndexOf(',')); // 77,82
If you are unsure if the string has at least one ,, you can validate before performing a Substring:
var a = "77,82,83";
var lastIndex = a.LastIndexOf(',');
if (lastIndex > 0)
var newString = a.Substring(0, lastIndex);
Update:
If you want to remove specific values from any position:
Split the string -> Remove the values using Where -> Join them with , separator
a = string.Join(",", a.Split(',').Where(i => i != "83"));
Here's a fiddle
You might need to clarify the question slightly but I think you're asking for the following:
var a = "72,82,83";
var group = a.Split(',').ToList();
int position = group.FindIndex(p => p.Contains("83"));
group.RemoveAt(position);
You can make the item you're looking for in the Contains query a parameter.
I think the problem you're having with your original code is that the foreach is a loop over each item in the array, so you're trying to remove "83" on each pass.

Compare two values and get data in between them

I have two variables 2016-V-0049 and 2016-V-0070. Is there a way in which I can compare them and get all the missing data between them while comparing the last numbers. So in this case I want the result to be 2016-V-0050,2016-V-0051,2016-V-0052...etc.
Also can I have repeatable patterns like comparing 2016P13 and 2016P25(NumberWordNumber) and getting the missing numbers in between.
Sorry for not including what I have tried. Here's what I did and which works. I was just looking for more patterns which are generic.
string s = "2016-s-89";
string p = "2016-s-95";
var start = Convert.ToInt32(Regex.Match(s, #"\d+$").Value) +1;
var end = Convert.ToInt32(Regex.Match(p, #"\d+$").Value);
var index = Regex.Match(s, #"\d+$").Index;
string data = s.Substring(0, index);
List<string> newCases = new List<string>();
while (start < end)
{
string newCaseNumber = string.Format("{0}{1}", data, start);
newCases.Add(newCaseNumber);
start++;
}
Once you can define step by step what you actually want your code to do, the implementation is trivial to research and put together. In steps, you want this:
Parse the input string denoting the starting number, so you can obtain the numeric part you're interested in.
Now you have a numeric string, but it's still a string. Parse it to an integer so you can later perform arithmetic operations on it, such as incrementing it by one.
Repeat 1 & 2 for the string denoting the ending number.
Loop over the numbers between the start and end number, and rebuild the original string with the new number.
A naive implementation to do that looks like this:
string inputStart = "2016-V-0049";
string inputEnd = "2016-V-0070";
string pattern = #"[0-9]{4}\-[A-Z]{1}\-([0-9]{4})";
var regex = new Regex(pattern);
var match = regex.Match(inputStart);
var numberStart = int.Parse(match.Groups[1].Value);
match = regex.Match(inputEnd);
var numberEnd = int.Parse(match.Groups[1].Value);
for (int currentNumber = numberStart + 1; currentNumber < numberEnd; currentNumber++)
{
Console.WriteLine("2016-V-{0:0000}", currentNumber);
}
But this doesn't do input checking (start < end, start and end actually conforming to the pattern), doesn't support different patterns (the pattern and rebuild string are hardcoded) and assumes the "2016-V-" part of the string to always be the same.
You should use substring() function and convert to integer like this code:
var min = "2016-V-0049";
var max = "2016-V-0070";
var a = min.Substring(7);
var b = max.Substring(7);
int convertableVariable1 = int.Parse(a);
int convertableVariable2 = int.Parse(b);
for (int i = convertableVariable1; i < convertableVariable2; i++){
Console.WriteLine("2016-V-{0:0000}",i);
}
Console.WriteLine("Difference :{0}", convertableVariable2 - convertableVariable1);

When using indexof and substring how do i parse the right start and end indexs ? And how do i encode hebrew chars?

I have this code:
string firstTag = "Forums2008/forumPage.aspx?forumId=";
string endTag = "</a>";
index = forums.IndexOf(firstTag, index1);
if (index == -1)
continue;
var secondIndex = forums.IndexOf(endTag, index);
result = forums.Substring(index + firstTag.Length + 12, secondIndex - (index + firstTag.Length - 50));
The string i want to extract from is for example:
הנקה
What i want to get is the word after the title only this: הנקה
And the second problem is that when i'm extracting it i see instead hebrew some gibrish like this: ������
One powerful way to do this is to use Regular Expressions instead of trying to find a starting position and use a substring. Try out this code, and you'll see that it extracts the anchor tag's title:
var input = "הנקה";
var expression = new System.Text.RegularExpressions.Regex(#"title=\""([^\""]+)\""");
var match = expression.Match(input);
if (match.Success) {
Console.WriteLine(match.Groups[1]);
}
else {
Console.WriteLine("not found");
}
And for the curious, here is a version in JavaScript:
var input = 'הנקה';
var expression = new RegExp('title=\"([^\"]+)\"');
var results = expression.exec(input);
if (results) {
document.write(results[1]);
}
else {
document.write("not found");
}
Okay here is the solution using String.Substring() String.Split() and String.IndexOf()
String str = "הנקה"; // <== Assume this is passing string. Yes unusual scape sequence are added
int splitStart = str.IndexOf("title="); // < Where to start splitting
int splitEnd = str.LastIndexOf("</a>"); // < = Where to end
/* What we try to extract is this : title="הנקה">הנקה
* (Given without escape sequence)
*/
String extracted = str.Substring(splitStart, splitEnd - splitStart); // <=Extracting required portion
String[] splitted = extracted.Split('"'); // < = Now split with "
Console.WriteLine(splitted[1]); // <= Try to Out but yes will produce ???? But put a breakpoint here and check the values in split array
Now the problem, here you can see that i have to use escape sequence in an unusual way. You may ignore that since you are simply passing the scanning string.
And this actually works, but you cannot visualize it with the provided Console.WriteLine(splitted[1]);
But if you put a break point and check the extracted split array you can see that text are extracted. you can confirm it with following screenshot

Categories