Link to home
Start Free TrialLog in
Avatar of Tony_k
Tony_k

asked on

Formatting a String in C#

I want to write a property in C# to test the format of a string called Vcode:
The following format are valid: M1M1M1, M1M M1M(for this one I I have to create a function to eliminate the space between M1M and M1M), M1M-M1M (for this one I have to eliminate the dash - and make it like M1M1M1)
and this property will be valid for the above and not valid for the format below:
 // Not Valid: M1M1M1A, M1M-M1MA, 73120, MMM-111
Avatar of jamesrh
jamesrh
Flag of United States of America image

are you trying to create a function or a property in a class?  M represents? and 1?
you can use a combination of regular expression and string replace to achieve the result.  I can give you more specific info once I know the answers to above.
I also use Functions / Property to validate data.
Two reasons:
  • Regular exprexsions are cryptic, no debugable, No documentable.
  • Functions / Property can raise exceptions especific for each error.
To develop the validation code, I use states. This simplifies a lot the code.
The sample code is ilustrate the concept.

    'Format: [-][Days{d,Space}][Horas][{h,':'}[Minutos]]
    <DebuggerStepThrough()> _
    Public Shared Function Parse(ByVal Dato As Object) As Int32
        Dim s As String = TryCast(Dato, String) 'Permite DbNull    
        If s Is Nothing Then Return 0
        s = s.Trim
        Dim v, ac, state As Integer, LastCharDigit, Negativo As Boolean
        For n As Integer = 0 To s.Length - 1
           Dim Digit As Integer = CharUnicodeInfo.GetDigitValue(s, n) '-1 si no es dígito
           If Digit >= 0 Then v = v * 10 + Digit : LastCharDigit = True : Continue For
           Select Case Char.ToLower(s(n))
                Case "d"c
                    If state = 0 Then state = 1 : ac = v * 1440 : v = 0 Else Throw New FormatException("Invalid Format - d")
                Case ":"c, "h"c
                    If state < 2 Then state = 2 : ac += v * 60 : v = 0 Else Throw New FormatException("Invalid Format - :")
                Case " "c : If LastCharDigit = False Then Continue For
                            If state > 0 Then Throw New FormatException("Espacio inválido")
                            state = 1 : ac = v * 1440 : v = 0 'Asumo "d"c
                Case "-"c : If n = 0 Then Negativo = True Else Throw New FormatException("Invalid Format - Caracter invalido")
                Case Else : Throw New FormatException("Invalid Format - Caracter invalido")
           End Select
           LastCharDigit = False
        Next
        If state < 2 Then v *= 60 'Por defecto Horas
        ac += v
        Return If(Negativo, -ac, ac)
    End Function

Open in new window

The idea of course would be to use the regular expression and string replacement inside a function or property.
Yeah... there are a few things wrong with the code posted above:
  1. It's in Spanish
  2. It's in VB
  3. It's in VB
  4. I'm not sure what "concept" is really even being illustrated.
  5. It's in VB.
Barf.
Author: please be more specific as to your request. What is the purpose of this validation? Do you have any resolution preferenes (eg do you prefer not to use RegEx?)? Let us know.
Avatar of Tony_k
Tony_k

ASKER

I want to write a property in C# to test the format of a string called Vcode that is in a constructor, so the user is assigning a string input called Vcode I want to test if this string has a format like the following:

LetterDigitLetterDigitLetterDigit (eg:P6T4K9) and sometimes the user assigns a string with a space between the Letter and the Digit, like LetterDigitLetter DigitLetterdigit (eg: P7Y 8L4) I want to eliminate any space between the letters and the digits in the string and concatenate the whole thing (maybe we can use the Trim Function to eliminate the space in between the characters and the digits. and finally the user might assign a string to the contructor that includes a dash between the letter and the digit, Like LetterDigit-LetterDigitLetterDigit (eg: J8-Y6K5) so I want to eliminate the dashes between the Letter and the digit and concatenate.(maybe also we can use the Trim function). All those scenarios mentioned above are valid input of string and anything else is not valid.

Can anyone help me to do this function in C#?
Avatar of Tony_k

ASKER

jamesrh: it can be a function to test the user input  VCODE too.
Avatar of Tony_k

ASKER

In other words the string Vcode should have this format: LetterDigitLetterDigitLetterDigit if a dash or a whiteSpace are in between they should be eliminated and then concatenated to have this format LetterDigitLetterDigitLetterDigit. anything else is not Valid.
Avatar of Tony_k

ASKER

Please find below what the function should achieve for user string input Vcode:

1. First  It will check if the string input contains whiteSpaces or Dashes
2. if so it should Eliminate the Whitespaces and the Dashes then Concatenate
3. Then it will Check the Length of the string is it is equal to 6 if so it will check the string format if it follows this format LetterDigitLetterDigitLetterDigit  

if all those 3 are true then return errorCode = 0  which is success or Valid

Else

If any of these is wrong  return errorCode = 3. Which is not Valid
Sorry to be a little dense with this, but I want to make sure I am really giving you what you are looking for.  You would like to be use this something like?:

Class1 myClass = new Class1("P6T4K9");
myClass.Vcode = "P7Y 8L4";
string currentVcode = myClass.Vcode;  // currentVcode now = "P7Y8L4"

If this is what you are trying to do, then you need something like the following code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;  
 
namespace Test
{
    class Class1
    {
        private string _Vcode;
 
        public string Vcode
        {
            get { return Vcode; }
            set
            {
                if (!Regex.IsMatch(value, @"[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d"))
                    //we throw an exception because setting a property can't return a value
                    //also when called by the constructor you can't send back a return code
                    throw new Exception("Invalid Vcode format");
 
                _Vcode = value.Replace(" ", "").Replace("-", "");
            }
        }
 
        //for a lot of reasons it is a good idea to have a default constructor
        public Class1()
        { 
            //do any initialization that doesn't depend on parameters
        }
 
        public Class1(string vCode)
        {
            //call it this way to invoke the validation code above.
            this.Vcode = vCode;   
        }
    }
}

Open in new window

The code I gave you has a couple of caveats.  1) P6T-4K9 and P6T 4K9 are valid. P6T--4K9, P6T -4K9, P6T  4K9, etc are not.  (I would be a small adjustment to change this if necessary)  2)  You could do everything will Regex and captures, however, I wanted to make the code a simple and straightforward as was practical.  If you want to make the change mentioned in item 1, we would then get rid of the replace and use regex and captures.
Avatar of Tony_k

ASKER

Jamesrh:
Thank you for code, I think it is answering my question, but I want to double check on this:

Does this expression:   !Regex.IsMatch(value, @"[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d"))
 take care of having this sequence of string format Valid:

LetterDigitLetter-DigitLetterDigit (eg:K2H-7A1) should eliminate the - and concatenate
or
LetterDigitLetter DigitLetterDigit (eg: K2H 7A1) should eliminate the whiteSpace and concatenate to be like this LetterdigitLetterDigitLetterDigit (eg:K2H7A1)

and does this expression take care of the length of the string just to be = 6 after concatenation otherwise not valid.

I want just to double check on the above to give you the 500 full points? :))




Avatar of Tony_k

ASKER

Jamesrh: Can you please transform everything to a function instead of a property?
The below is the code in function format.  Notice the regular expression is slightly different as my first example did not check for additional characters before and after.  So the regex tests for the following 3 formats for vCode coming in:  M1M1M1, M1M-1M1, M1M 1M1.  Anything else including additional characters before or after the pattern results in return 3.  The replace statement removes the space or dash if there is one.

You would call the code like so:
string testVcode = "K2H-7A1";
if(EvaluateVcode(ref testVcode) != 3)
   //do some stuff
  //at this point testVcode = K2H7A1
public int EvaluateVcode(ref string vCode)
{
  if (!Regex.IsMatch(value, @"^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$"))
     return 3;
 
  vCode = value.Replace(" ", "").Replace("-", "");  
  return 0;   
   
}

Open in new window

Avatar of Tony_k

ASKER

james:
When I build the project it is complaining about the value, im getting "the name 'value' does not exist in the current context".
I am using this reference below:
using System.Text.RegularExpressions;  


any solution about it?
ASKER CERTIFIED SOLUTION
Avatar of jamesrh
jamesrh
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
value was only vaild in the property scenario.
Avatar of Tony_k

ASKER

yep it works! thanks a million!!!