I am in need of parsing an array or characters that is a fixed length but can have just about any combination of letter or number. My 50 digit array looks like this: NL1NAMEOFCO-B032144221111000100600000-A35499001
This array represents a vast combination of settings within our product. I need to extract all reference designators in the array. The first 3 characters represent a particular model NL1, the next 8 characters represent a company NAMEOFCO. The ‘-‘ will always be in the same location. The B (digit 13) represents some value, etc, etc. Also, some values are represented by 2 digits. Digits 20 & 21 (which store the value 22), represent some specific settings.
So by now you get the idea. I can parse the array and extract the values I need by using the following code:
String Company = ConfigCode[3].ToString() +
ConfigCode[4].ToString() +
ConfigCode[5].ToString() +
ConfigCode[6].ToString() +
ConfigCode[7].ToString() +
ConfigCode[8].ToString() +
ConfigCode[9].ToString() +
ConfigCode[10].ToString();
This works without any problems, but to me, there should be an easier way of doing this. I would have thought the following would work, but it does not.
String Company = ConfigCode[3..10].ToString();
Can someone explain to me why it doesn’t work and what would be a better way of extracting the information I need?
Thanks!
I believe that String.Substring method is what you're looking for. The signature for the overloaded method you're looking for is:
public string Substring(
int startIndex,
int length
)
The documentation for it is here: http://msdn.microsoft.com/en-us/library/aka44szs(v=vs.110).aspx
For example, your Company name would be (going by the description of a character length of 8):
string CompanyName = configCode.Substring(3, 8);
Like mentioned before, you can use the Substring extension method like so:
String Company = ConfigCode.Substring(3, 8);
The square-bracket operators for strings, like in ConfigCode[3], actually return individual chars at that specific index. And C# isn't as pretty as other programming languages where stuff like array[3..10] actually gives you a portion of an array (or in this case, a string).
Related
I'm new to C#. I'm parsing for a lot number in a 2D barcode. The actual lot number 'A2351' is hidden in this barcode string "+M727PP011/$$3201001A2351S". I would like to break this barcode up in separate string blocks but the delimiters are not consistent.
The letter prefix in front of the 4 digit lot number can be a 'A', 'P', or a 'D' There is a single letter following the lot number that can be ignored.
string Delimiter = "/$$3";
//barcode format:M###PP###/$$3 ddmmyy lotnumprefix 'A' followed by lotNum
string lotNum= "+M727PP011/$$3201001A2351S";
string[] split = lotNum.Split(new[] {Delimiter}, StringSplitOptions.None);
How do I extract the lot number after the date?
Based on your initial example and then the subsequent edit in which you showed how you are solving this, it sounds like the lot number is always in the same place. It would be cleaner (and more in line with standard C# code) to use a single call to string.Substring(int,int) rather than the two lines you are using which also require pulling in the VB library. You just need to call Substring and give it the starting index and the length.
So this code:
string lotNum = Strings.Right(barcode, 6);
lotNum = lotNum.Remove((lotNum.Length - 1), 1);
Can be done with this single substring call:
string lotNum = barcode.Substring(barcode.Length - 6, 5);
Edit
Just further clarification on why it might be better to use the call to Substring. In C# string objects are immutable. That means that when you make the call to Strings.Right you are getting back a new string object. When you then call lotNum.Remove you do not "remove" a character from the existing string, a new string is allocated with the character(s) removed and is returned to you. So with your code there are two new string allocations when trying to extract the lot number. When you make the call to Substring you will get back a new string, but instead of getting a new string that you immediately then modify and get a second new string, you will only need to allocate one new string to extract the lot number. In the example you have given there probably would not be any noticeable performance/memory issue, but it is something that could potentially lead to trouble if this code was in a tight loop or something like that.
If you're just trying to get the lot number, it's really dependent on the format of the input string (is it a consistent length, are there any reliable prefixes/suffixes relative to the data you're trying to parse that you can reference from, etc). It looks like your data is definable by its static position in the string, so it looks like you could use the substring
(with an index of 20?) method to accomplish what you want.
Maybe someone in either of the camps can tell me whats going on here:
Python:
temp = int('%d%d' % (temp2, temp3)) / 10.0;
I'm working on parsing temperature data, and found a piece of python that I can't understand. What is going on here? Is python adding together two numbers here and casting them to int, and then divide by 10?
C# might look like:
temp = ((int)(temp2+temp3))/10;
But I am not sure what that % does? Data is jibberish so I don't know what is correct translation for that line in python to C#
In C# it looks like:
var temp = int.Parse(temp2.ToString() + temp3.ToString())/10f;
or:
var temp = Convert.ToInt32(string.Format("{0}{1}", temp2, temp3))/10f;
this is similar: What's the difference between %s and %d in Python string formatting?
name = 'marcog'
number = 42
print '%s %d' % (name, number)
will print marcog 42. Note that name is a string (%s) and number is an integer (%d for decimal).
See
http://docs.python.org/library/stdtypes.html#string-formatting-operations
for details.
So it seems like the "%" is just telling python to put the values on the right into the placeholders on the left.
from the documentation linked in the answer I quoted:
Given format % values (where format is a string or Unicode object), % conversion specifications in format are replaced with zero or more elements of values. The effect is similar to the using sprintf() in the C language. If format is a Unicode object, or if any of the objects being converted using the %s conversion are Unicode objects, the result will also be a Unicode object.
Would probably want to set up a python script and try it out, placing your own values into the variables.
We have a requirement to display bank routing/account data that is masked with asterisks, except for the last 4 numbers. It seemed simple enough until I found this in unit testing:
string.Format("{0:****1234}",61101234)
is properly displayed as: "****1234"
but
string.Format("{0:****0052}",16000052)
is incorrectly displayed (due to the zeros??): "****1600005252""
If you use the following in C# it works correctly, but I am unable to use this because DevExpress automatically wraps it with "{0: ... }" when you set the displayformat without the curly brackets:
string.Format("****0052",16000052)
Can anyone think of a way to get this format to work properly inside curly brackets (with the full 8 digit number passed in)?
UPDATE: The string.format above is only a way of testing the problem I am trying to solve. It is not the finished code. I have to pass to DevExpress a string format inside braces in order for the routing number to be formatted correctly.
It's a shame that you haven't included the code which is building the format string. It's very odd to have the format string depend on the data in the way that it looks like you have.
I would not try to do this in a format string; instead, I'd write a method to convert the credit card number into an "obscured" string form, quite possibly just using Substring and string concatenation. For example:
public static string ObscureFirstFourCharacters(string input)
{
// TODO: Argument validation
return "****" + input.Substring(4);
}
(It's not clear what the data type of your credit card number is. If it's a numeric type and you need to convert it to a string first, you need to be careful to end up with a fixed-size string, left-padded with zeroes.)
I think you are looking for something like this:
string.Format("{0:****0000}", 16000052);
But I have not seen that with the * inline like that. Without knowing better I probably would have done:
string.Format("{0}{1}", "****", str.Substring(str.Length-4, 4);
Or even dropping the format call if I knew the length.
These approaches are worthwhile to look through: Mask out part first 12 characters of string with *?
As you are alluding to in the comments, this should also work:
string.Format("{0:****####}", 16000052);
The difference is using the 0's will display a zero if no digit is present, # will not. Should be moot in your situation.
If for some reason you want to print the literal zeros, use this:
string.Format("{0:****\0\052}", 16000052);
But note that this is not doing anything with your input at all.
I have 5 strings, let's call them
EarthString
FireString
WindString
WaterString
HeartString
All of them can have varying length, any of them can be empty, or can be very long (but never null).
These 5 strings are very good friends, and every weekend they are concatenated to form a result string using this c# statement
ResultString = EarthString + FireString + WindString + WaterString + HeartString
Depending on the values of these strings, sometimes (only sometimes), ResultString will contain "Captain Planet" as a substring.
My question is, how do I manipulate each of the 5 strings before they are concatenated, so that when they are combined, "Captain Planet" will never appear as a substring in the resultant string?
The only way I can think of right now is to examine each character in each string, in sequential order, but that seems very tedious. Since each of the 5 good friends strings can be of any length, examining the characters individually will also require some kind of concatenation before we can determine whether any character need to be dropped.
Edit: The resultant string is a filtered version of the 5 strings concatenated together, all the other content remain the same except the "Captain Planet" string is dropped. Yes, i'm looking for a solution which allows the 5 strings to be manipulated before concatenation. (this is actually a simplification of a bigger programming problem i'm encountering). Thanks guys.
If you want to do it pre-concat you could
Assign the start and end of each string a numeric value based on the portion of "CaptainPlanet" they contein. Ex: if Air = "net the big captain" then it would get 3 for a start value and 7 for an end value. to determine if you could concat 2 values safely you would just check to see if the end of the left string + start of the right string were not equal to the total length of "CaptainPlanet". If you had very large strings this would allow you to inspect just the first x and last x characters of the string to compute the start/end value.
This solution doesn't account for short strings like ei air = "Cap" , earth ="tain" and fire="Planet". In that case you would need to have a special case for tokens that are shorter than the length of "CaptainPlanet" For those.
Is there a particular reason you can't just do this?
ResultString.Replace("CaptainPlanet", "x");
If it doesn't matter how many chars will be dropped, you can remove f.e. all 'C' in all strings.
The original answer cleared all of the strings, but as pointed out by J.Steen, there was already a formulation of the expected output. So there we go.
Run elementString.Replace("Captain Planet", "") on every substring.
Now you have to identify all the prefixes / suffixes of "Captain Planet" on each of the substrings, and keep that information so that it can be processed before contatenation. That is, e.g. if the substring ends with "Capt", then you should have an information that "substring contains at the end a prefix of the 4 first letters of 'Captain Planet'". You also have to consider the cases of complete substrings (e.g. one of the strings is "ptain Pla"). The problem also becomes more complex if any of the e.g. prefixes can be recursive or repeated (e.g. "CaptainCap" contains 2 kinds of valid prefixes for "CaptainCaptain", and "apt" can be found at two locations in the resulting string);
You process that information before concatenation so that the result string has the same thing as ResultString.Replace("Captain Planet", ""). Congratulations, you have made your program much more complex than necessary!
But in short, you cannot get both the result that you want (all of the substrings intact except for the combined result output) and do the processing wholly before the concatenation step.
I'm not sure if "key value" is correct word for it as there are few formats I believe, what im talking about is http://pastebin.com/XJVx1dB5 this is format where 88 is Z etc. I hope im clear.
I have tried many things, but convert from string function of keys converter class is the only one that is remotely close. The problem is, it converts "x" to 88 as I wanted, however it fails to convert " " or "[" because it expects "SPACE"(string) and not a single space as char I believe.
I used it like this, maybe there is another(correct?) version of using it:
((int)kc.ConvertFromString(s))
So what I want to do is to get that chars of mine to code ones. How can I achieve this ?
Try something like:
var stringValue = " ";
var intValue = (int)stringValue[0];
A string is an 'array of chars' - so waht you need to do is get the char [in this case the first one] - and convert that to an int - in this case simply by casting.
If you want to do it with the enum, then you're going to have to write a manual system to convert " " to Keys.Space .
If you review your enum Keys carefully, you will see there is no value for [.
In fact, that character (on my keyboard) is reported as Oem4.
This code works:
var c = kc.ConvertFromString("Oem4");
However,
var c = kc.ConvertFromString("[");
Cannot work because [ is not a valid member of the enum you are converting from.
What do you want to do once you have converted the string? That may help guide a better answer to your question.