Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Regex.Replace - replacing substrings using System.Text.RegularExpressions.Regex

Posted on 2004-09-25
17
1,249 Views
Last Modified: 2012-08-13
I have a date string like "Sep-20-2004" which I need to convert to "9/20/2004" using regular expressions. The source string can, of course, be any date, like "Jan-1-2004", Jul-04-2004" etc.

I know how to convert it using DateTime, String.Replace etc. I understand that there may be more efficient ways of doing this. I need regex based solution.

What I am looking for is something like
string olddateformat = "Sep-20-2004";
string pattern = @".....";
string replace= @"......";
string newdateformat = Regex.Replace(olddateformat, pattern, replace);

0
Comment
Question by:lisa66
  • 7
  • 5
  • 2
  • +2
17 Comments
 
LVL 5

Expert Comment

by:TRUENEUTRAL
ID: 12152878
Is this what you are looking for?

            Dim regex As System.Text.RegularExpressions.Regex

            Dim olddateformat As String = "Sep-20-2004"
            Dim pattern(12) As String
            pattern(0) = "\W"
            pattern(1) = "[J|j][A|a][N|n]"
            pattern(2) = "[F|f][E|e][B|b]"
            pattern(3) = "[M|m][A|a][R|r]"
            pattern(4) = "[A|a][P|p][R|r]"
            pattern(5) = "[M|m][A|a][Y|y]"
            pattern(6) = "[J|j][U|u][N|n]"
            pattern(7) = "[J|j][U|u][L|l]"
            pattern(8) = "[A|a][U|u][G|g]"
            pattern(9) = "[S|s][e|E][p|P]"
            pattern(10) = "[O|o][C|c][T|t]"
            pattern(11) = "[N|n][O|o][V|v]"
            pattern(12) = "[D|d][e|E][C|c]"
            Dim newdateformat As String
            newdateformat = regex.Replace(olddateformat, pattern(0), "/")
            Dim i As Integer
            For i = 1 To 12
                  newdateformat = regex.Replace(newdateformat, pattern(i), i.ToString)
            Next

            MsgBox(newdateformat)

0
 
LVL 1

Author Comment

by:lisa66
ID: 12153150
Not really.
I am looking for doing it with one Replace, not in the loop (as I may not know in advance how many variations could be out there). This solution is similar to a string.Replace in the loop. I look for something I can dynamically change without changing code. I also know that it is possible to achieve using XSLT, but it looks like an overkill here.

Additional details:
The question I asked is a simplified form of what I really need. If I figure out how to that I will take it from there. Essentially neither input nor output is fixed. These two formats are only example of one case. So I need to be able to give a regex expression as an input at run-time that will replace and reformat input into output (at any given time, I know what is an input and output formats are).
Another example may be that I need to subtract a fixed number (let's say 1 for simplicity),  from a months number so that "Jan-1-2004" will be transformed into "0/1/2004", "Jul-4-2004" into "3-4-2004" (Don't ask me who might need that. There are smart people out there ...). However, down the road, user should be able to change regex inputs and subtract  2 or add 1 etc. As number is fixed it is just a substitution. Or he may want to do something else....

 


0
 
LVL 7

Expert Comment

by:jackiechen858
ID: 12154475
I can't do it in one Replace,  this is what I would do it.

                  Hashtable ht = new Hashtable();
                  ht.Add("Jan",1);
                  ht.Add("Feb",2);
                  ht.Add("Mar",3);
                  ht.Add("Apr",4);
                  ht.Add("May",5);
                  ht.Add("Jun",6);
                  ht.Add("Jul",7);
                  ht.Add("Aug",8);
                  ht.Add("Sep",9);
                  ht.Add("Oct",10);
                  ht.Add("Nov",11);
                  ht.Add("Dec",12);


                  string strPat= "(?<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(?<day>\\d{1,2})-(?<year>\\d{4})";
                  System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(strPat);
                  string olddateformat = "Sep-20-2004";
                  System.Text.RegularExpressions.Match match = regex.Match(olddateformat);
                  string strNewString="";
                  if ( match.Success)
                  {
                        strNewString = string.Format("{0}/{1}/{2}",
                              ht[match.Groups[1].Value],match.Groups[2].Value,match.Groups[3].Value);

                  }
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 5

Expert Comment

by:TRUENEUTRAL
ID: 12156208
I do not think what you are asking for is possible without a lot more detail on the question.  

Are you asking for a way to replace part of a string using regex when you don't know what you are replacing, what the string looks like, or what you are replacing it with?  Sounds like you are trying to use regex to write regex.  in other words, that's what the regex class is for.  If you wish to use it, you need to know *something* about the data you are dealing with.

For instance, if you *knew* you had a lot of text (you don't know how much), and you knew you wanted to find every word in that text that ended in *er* (again, something you know), you could do it with instr(), however, you can do it much faster and more efficiently with regex.

Regex is not magic, however.   If you knew you wanted to find some words, but did not know what those words (or part of those words) was, no programming language in the world will help you.

Since you are asking questions about regex, however, I suspect you are not a beginner but you *are* trying to be secretive in some way.  Nothing wrong with that, but without more that generalities it may be impossible for anyone to provide you with an answer.
0
 
LVL 1

Author Comment

by:lisa66
ID: 12156407
I am sorry, I did not try to be secretive. I tried to take out unneccessary complexities to make the question more focused. I would have added all needed meat later myself, this is not a problem.  

You are right, to make a transformation I should know what is input and output formats are. At any given time I know input format and output format. However, both could change and I (or somebody else) would know what these changes had been and what would be the current format. I also know that some transformation needs to be done between input and output. An example of the transformation could be replacing parts of the input (know at the time). The goal is to be able to pass to the code regex expressions (pattern, replacing pattern)  as parameters and be able to do a transformation (known at the point). However, the input and output format may change. While input is fairly stable, output is more volatile. I need to be able to adjust the expression without modifying the code. Again, I know how to do it with code modification, and I could write an XSLT. My boss wants it to be regex (code will not be allowed to change and XSLT is too much overhead). He thinks it should be possible :)
I also think that it should be fairly easy, I just do not get it :)

If I could write something like
string input = "Some_a stuff"; //or "Some_b stuff" or something else
string pattern = "(?<a>pattern_a)(?<b>pattern_b)...."; //pattern that will mark months in the earlier example
string replace_with =  "${a}=a${b}=b etc";         //replace each group with something
string out = Regex.Replace(input_string, pattern, replace_with)
and it would replace pattern_a in the input string with letter a in the output string, so that string out would contain "a Stuff" if pattern_a matches "Some_a" if "b Stuff" if pattern_b matches "Some_b" I would have been all set.

Hence in the example, a "Jan-1-2004" will be replaced with "0-1-2004", "Jul-4-2004" replaced with "6-4-2004" etc. However, the input format may change, number of input patterns may change (hence hashtable approach, while an interesting solution, will not work), output/transformation rules might change. All these changes will be known in advance and will require rewriting regex. That's ok, as long as code doesn't change and this new data can be passed to the application as a string parameter(s).  
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12157061
This is a very complex regular expression requirement, that may only be possible with some major contortion moves, that only a few expression masters can handle.  And for only 125 points!!!

Bob
0
 
LVL 5

Expert Comment

by:TRUENEUTRAL
ID: 12159543
I think I understand what you asking for.  Look at the following pseudocode and see if I have the gist of what you are trying to do

get user input for working_string
get user input for regex pattern to search for
get user input for replacement_string
output regex.replace(working_string, pattern, replacement_string)


If that is all you are after, you would just write a wrapper for the regex.replace function like so:

Private Function Replace(ByVal working As String, ByVal pattern As String, ByVal replacement As String) As String
Dim regex As System.Text.RegularExpressions.Regex
Replace = regex.Replace(working, pattern, replacement)
End Function

Since it sounds like you are going to require the user to enter the regex pattern themselves, you are doing nothing more than this.  If you are asking what the pattern would be for a complex replacement like the one given in you example, TheLearnedOne is right, you are going to need a big gun.  By big gun I mean a theoretical mathmatician.  Someone like that might hang out in the Perl section or in math & science (under Misc).  If that is the case, good luck!

For a better understanding of the complexity involved here, read:
http://www.evolt.org/article/rating/20/22700/
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12159621
I would be very interested to learn of a solution to this perplexing requirement.


My complete list of RegEx sources:

Regular Expressions:
Regular Expression Library
http://www.regexlib.com/

Regular Expressions Tutorial
http://www.regular-expressions.info/

The Complete Regular Expression Guide
http://www.devarticles.com/c/a/ASP/The_Complete_Regular_Expression_Guide/1/

Directory of ASP.NET Resources
http://www.123aspx.com/directory.aspx?dir=112

A Tao of Regular Expressions
http://sitescooper.org/tao_regexps.html

Pattern Matching and Regular Expressions
http://www.webreference.com/js/column5/



Bob
0
 
LVL 5

Expert Comment

by:TRUENEUTRAL
ID: 12162052
Here-here.

I will remain subscribed to this question.

If you find a solution exactly like what you are asking for, I will give YOU points to post it
:)
0
 
LVL 1

Author Comment

by:lisa66
ID: 12166453
TrueNeutral,

You are exactly right. I am looking for the expression I can feed to the pseudocode similiar to the one in your example. User will (or will not) provide an expression in the future. However, it is yours trully who needs to do it for the first time :(. I will post the solution if I find one. As I mentioned above XSLT transformation is possible while is expensive resource-wise. It may be easier to convince boss that regex is not as easy as it sounds, though. If rules doesn't allow to win, gentelman changes them :)

TheLearnedOne - is it really that complex? The Regex expression itself to mark possible groups is fairly straitforward. The part I missing is how to tell Replace function to perform certain replacement (like if there's group "one" replace it with "1", if there's group "two" replace it with "b", if there's no group "two" or group "two" is empty do nothing ... ). Can you show me an example of "contortion move"?

Anyway, if there's no easy way out of this I'll keep my points and go to work on teaching the boss about an enormous complexity of the regex solution :)
0
 
LVL 5

Expert Comment

by:TRUENEUTRAL
ID: 12168984
lisa,
In excel there is something called a choose function, look at that.   If that will not solve your problem, there is probably not a way to do it with regex and your time is more wisely spent explaining to your boss that XSLT isn't all that bad.
0
 
LVL 7

Expert Comment

by:jackiechen858
ID: 12181040
I have a samilliar question posted in

http://www.experts-exchange.com/Web/Web_Languages/JavaScript/Q_21149594.html

is there anybody want to look at it?
0
 
LVL 5

Expert Comment

by:TRUENEUTRAL
ID: 12183284
Jackie, like we suggested to lisa, you already know the values you are looking for.

Lisa does not seem to know in advance what those walues are or what they will be replaced with.

0
 
LVL 1

Author Comment

by:lisa66
ID: 12186346
Truenetral,

That is not exactly true. I DO now what I want to convert to what. I do not know if these requirments will change in the future. Hence the requirment to be able to make neccessary changes using regex expression without the need to make any changes to the compiled code


0
 
LVL 5

Assisted Solution

by:TRUENEUTRAL
TRUENEUTRAL earned 50 total points
ID: 12186428
ok, so declare the regex expressions and replacement values in a array like this:

      Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dim pattern() As String = {"[S|s][e|E][p|P]", "[O|o][C|c][T|t]", "[N|n][O|o][V|v]", "[D|d][e|E][C|c]"}
            Dim replace() As String = {"9", "10", "11", "12"}

            Dim value As String = "Sep-20-2004"
            reformat(value, pattern, replace)
            MsgBox(value)

            value = "Oct-10-2004"
            reformat(value, pattern, replace)
            MsgBox(value)

            value = "Nov-11-2004"
            reformat(value, pattern, replace)
            MsgBox(value)


      End Sub
      Private Sub reformat(ByRef Value As String, ByVal pattern() As String, ByVal replace() As String)
            Dim regex As System.Text.RegularExpressions.Regex

            Dim i As Integer
            For i = 0 To UBound(pattern)
                  Value = regex.Replace(Value, pattern(i), replace(i))
            Next


      End Sub
0
 
LVL 12

Accepted Solution

by:
farsight earned 75 total points
ID: 12207886
TRUENEUTRAL provides a code-based solution.  (Thanks)
I'm extending it a bit to support multiple replacements.  His/her example could be converted to a string-based solution as follows.  (Manually written -- almost code)

Private Sub Example()
  Dim delim As String = ";;"
  Dim multipattern As String = "[S|s][e|E][p|P];;9;;[O|o][C|c][T|t];;10;;[N|n][O|o][V|v];;11;;[D|d][e|E][C|c];;12"}

  Dim value As String = "Sep-20-2004"
  Debug.WriteLine(MultiReplace(value, multipattern, delim))
End Sub

Private Function MultiReplace(ByVal text As String, ByVal multipattern As String, ByVal delim As String) As String
  Dim regex As New System.Text.RegularExpressions.Regex
  ' I've forgotten what namespace Split is in???
  Dim splitPattern As String() = String.Split(input, delim)
  ' Loop through all the pattern and replacement pairs.
  For index As Integer = 0 To splitPattern .Length Step 2
    ' Read a pattern from the array.
    Dim pattern As String = splitPattern(index)
    ' ... and a replacement from the array, too.
    Dim replacement As String = splitPattern(index+1)
    text = regex.Replace(text , pattern, replacement)
  Next index
  Return text
End Function

I think that gives you the idea.  Pardon any errors.
0
 
LVL 1

Author Comment

by:lisa66
ID: 12221484
Why I did not think about that myself? Why I am not so smart?
Good idea - just delimit these simple patterns. I've been trying to create that gigantic change anything into anything pattern, when solution was so simple
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question