I have a string that looks like (the * is literal):
clp*(seven digits)1*
I want to change it so that it looks like:
clp*(seven digits)(space)(space)1*
I'm working in C# and built my search pattern like this:
Regex regAddSpaces = new Regex(#"CLP\*.......1\*");
I'm not sure how to tell regex to keep the first 11 characters, add two spaces and then cap it with 1*
Any help is appreciated.
No need to use regex here. Simple string manipulation will do the job perfectly well.
var input = "clp*01234561*";
var output = input.Substring(0, 11) + " " + input.Substring(11, 2);
I agree with Noldorin. However, here's how you could do it with regular expressions if you really wanted:
var result = Regex.Replace("clp*12345671*", #"(clp\*\d{7})(1\*)", #"$1 $2");
If you just want to replace this anywhere in the text you can use the excluded prefix and suffix operators...
pattern = "(?<=clp*[0-9]{7})(?=1*)"
Handing this off to the regex replace with the replacement value of " " will insert the spaces.
Thus, the following one-liner does the trick:
string result = Regex.Replace(inputString, #"(?<=clp\*[0-9]{7})(?=1\*)", " ", RegexOptions.IgnoreCase);
Here is the regex, but if your solution is as simple as you stated above Noldorin's answer would be a clearer and more maintainable solution. But since you wanted regex... here you go:
// Not a fan of the 'out' usage but I am not sure if you care about the result success
public static bool AddSpacesToMyRegexMatch(string input, out string output)
{
Regex reg = new Regex(#"(^clp\*[0-9]{7})(1\*$)");
Match match = reg.Match(input);
output = match.Success ?
string.Format("{0} {1}", match.Groups[0], match.Groups[1]) :
input;
return match.Success;
}
Related
I just want to replace a portion of a string only if matches the given text.
My use case is as follows:
var text = "<wd:response><wd:response-data></wd:response-data></wd:response >";
string result = text.Replace("wd:response", "response");
/*
* expecting the below text
<response><wd:response-data></wd:response-data></response>
*
*/
I followed the following answers:
Way to have String.Replace only hit "whole words"
Regular expression for exact match of a string
But I failed to achieve what I want.
Please share your thoughts/solutions.
Sample on
https://dotnetfiddle.net/pMkO8Q
In general, you should really be parsing and manipulating XML as XML, using functions that know how XML works and what's legal in the language. Regex and other naive text manipulation will often lead you into trouble.
That said, for a very simple solution to this specific problem, you can do this with two replaces:
var text = "<wd:response><wd:response-data></wd:response-data></wd:response >";
text.Replace("wd:response>", "response>").Replace("wd:response ", "response ")
(Note the spaces at the end of the parameters to the second replace.)
Alternatively use a regex similar to "wd:response\s*>"
The easiest way to achieve your result as per your .net fiddle is use the replace as below.
string result = text.Replace("wd:response>", "response>");
But proper way to achieve this is parsing using XML
You can capture the string wd-response in a capturing group and replace using Regex.Replace using the MatchEvaluator like this.
Regex explanation - <[/]?(wd:response)[\s+]?>
Match < literally
Match / optionally hence the ?
Match the string wd:response and place it in a capturing group enclosed with ()
Match one or more optional whitespace [\s+]?
Match > literally
public class Program
{
public static void Main(string[] args)
{
string text = "<wd:response><wd:response-data></wd:response-data></wd:response >";
string replacePattern = "response";
string pattern = #"<[/]?(wd:response)[\s+]?>";
string replacedPattern = Regex.Replace(text, pattern, match =>
{
// Extract the first group
Group group = match.Groups[1];
// Replace the group value with the replacePattern
return string.Format("{0}{1}{2}", match.Value.Substring(0, group.Index - match.Index), replacePattern, match.Value.Substring(group.Index - match.Index + group.Length));
});
Console.WriteLine(replacedPattern);
}
}
Outputting:
<response><wd:response-data></wd:response-data></response >
I have a string which I want to manipulate. Problem is that the replacement contains also regular expressions.
var result = Regex.Replace("Abc", "\r\nAbc\r\n", "\r\n");
// or something like that, it can be also \t and so on...
But the result is not a newline, but the string "\r\n".
PS: By the way, if I want to replace something by nothing, as very simple example:
Regex.Replace("abc", "abc", "")
regex seems to fail. Cannot strings are replaced by an empty string?
You can just use as follows instaed of using regex.
string result = "abc".Replace("abc", string.empty);
Try this:
var result = Regex.Replace("Abc", "\r\nAbc\r\n", System.Environment.NewLine);
Try adding the string literal # identifier before your regex.
var result = Regex.Replace("Abc", #"\r\nAbc\r\n", "\r\n");
My guess it that they are being read in as escape characters before they get to the regex engine.
Basically, the pattern getting passed in is this:
"
Abc
"
Intead of this:
"\r\nAbc\r\n"
I have a fairly long string that contains sub strings with the following format:
project[1]/someword[1]
project[1]/someotherword[1]
There will be about 10 or so instances of this pattern in the string.
What I want to do is to be able to replace the second integer in square brackets with a different one. So the string would look like this for instance:
project[1]/someword[2]
project[1]/someotherword[2]
I''m thinking that regular expressions are what I need here. I came up with the regex:
project\[1\]/.*\[([0-9])\]
Which should capture the group [0-9] so I can replace it with something else. I'm looking at MSDN Regex.Replace() but I'm not seeing how to replace part of a string that is captured with a value of your choosing. Any advice on how to accomplish this would be appreciated. Thanks much.
*Edit: * After working with #Tharwen some I have changed my approach a bit. Here is the new code I am working with:
String yourString = String yourString = #"<element w:xpath=""/project[1]/someword[1]""/> <anothernode></anothernode> <another element w:xpath=""/project[1]/someotherword[1]""/>";
int yourNumber = 2;
string anotherString = string.Empty;
anotherString = Regex.Replace(yourString, #"(?<=project\[1\]/.*\[)\d(?=\]"")", yourNumber.ToString());
Matched groups are replaced using the $1, $2 syntax as follows :-
csharp> Regex.Replace("Meaning of life is 42", #"([^\d]*)(\d+)", "$1($2)");
"Meaning of life is (42)"
If you are new to regular expressions in .NET I recommend http://www.ultrapico.com/Expresso.htm
Also http://www.regular-expressions.info/dotnet.html has some good stuff for quick reference.
I've adapted yours to use a lookbehind and lookahead to only match a digit which is preceded by 'project[1]/xxxxx[' and followed by ']':
(?<=project\[1\]/.*\[)\d(?=\]")
Then, you can use:
String yourString = "project[1]/someword[1]";
int yourNumber = 2;
yourString = Regex.Replace(yourString, #"(?<=project\[1\]/.*\[)\d(?=\]"")", yourNumber.ToString());
I think maybe you were confused because Regex.Replace has lots of overloads which do slightly different things. I've used this one.
If you want to process the value of a captured group before replacing it, you'll have to separate the different parts of the string, make your modifications and put them back together.
string test = "project[1]/someword[1]\nproject[1]/someotherword[1]\n";
string result = string.Empty;
foreach (Match match in Regex.Matches(test, #"(project\[1\]/.*\[)([0-9])(\]\n)"))
{
result += match.Groups[1].Value;
result += (int.Parse(match.Groups[2].Value) + 1).ToString();
result += match.Groups[3].Value;
}
If you just want to replace text verbatim, it's easier: Regex.Replace(test, #"abc(.*)cba", #"cba$1abc").
you can use String.Replace (String, String)
for example
String.Replace ("someword[1]", "someword[2]")
RegEx has always confused me.
I have a string like this:
IDE\DiskDJ205GA20_____________________________A3VS____\5&1003ca0&0&0.0.0
Or Sometimes stored like this:
IDE\DiskSJ305GA23_____________________________PG33S\6&2003Sa0&0&0.0.0
I want to get the 'A3VS' or 'PG33S' string. It's my firmware and is varied in length and type. I used to use:
string[] split = PNP.Split('\\'); //where PHP is my string name
var start = split[1].LastIndexOf('_');
string mystring = split[1].Substring(start + 1);
But that only works for strings that don't end with __ after the firmware string. I noticed that some have an additional random '_' after it.
Is RegEx the way to solve this? Or is there another way better
just without RegEx it can be expressed like this:
var firmware = PNP.Split(new[] {'_'}, StringSplitOptions.RemoveEmptyEntries)[1].Split('\\')[0];
string s = split[1].TrimEnd('_');
string mystring = s.Substring(s.LastIndexOf('_') + 1);
If you want the RegEX way to do it here it is:
Regex regex = new Regex(#"\\.*_+(?<firmware>[A-Za-z0-9]+)_*\\");
var m1 = regex.Match("IDE\DiskSJ305GA23_____________________________PG33S\6&2003Sa0&0&0.0.0");
var g1 = m1.Groups["firmware"].Value;
//g1 == "PG33S"
Keep in mind you have to use [A-Za-z0-9] instead of \w in the capture subexpression since \w also matches an underscore (_).
I am hopeless with regex (c#) so I would appreciate some help:
Basicaly I need to parse a text and I need to find the following information inside the text:
Sample text:
KeywordB:***TextToFind* the rest is not relevant but **KeywordB: Text ToFindB and then some more text.
I need to find the word(s) after a certain keyword which may end with a “:”.
[UPDATE]
Thanks Andrew and Alan: Sorry for reopening the question but there is quite an important thing missing in that regex. As I wrote in my last comment, Is it possible to have a variable (how many words to look for, depending on the keyword) as part of the regex?
Or: I could have a different regex for each keyword (will only be a hand full). But still don't know how to have the "words to look for" constant inside the regex
The basic regex is this:
var pattern = #"KeywordB:\s*(\w*)";
\s* = any number of spaces
\w* = 0 or more word characters (non-space, basically)
() = make a group, so you can extract the part that matched
var pattern = #"KeywordB:\s*(\w*)";
var test = #"KeywordB: TextToFind";
var match = Regex.Match(test, pattern);
if (match.Success) {
Console.Write("Value found = {0}", match.Groups[1]);
}
If you have more than one of these on a line, you can use this:
var test = #"KeywordB: TextToFind KeyWordF: MoreText";
var matches = Regex.Matches(test, #"(?:\s*(?<key>\w*):\s?(?<value>\w*))");
foreach (Match f in matches ) {
Console.WriteLine("Keyword '{0}' = '{1}'", f.Groups["key"], f.Groups["value"]);
}
Also, check out the regex designer here: http://www.radsoftware.com.au/. It is free, and I use it constantly. It works great to prototype expressions. You need to rearrange the UI for basic work, but after that it's easy.
(fyi) The "#" before strings means that \ no longer means something special, so you can type #"c:\fun.txt" instead of "c:\fun.txt"
Let me know if I should delete the old post, but perhaps someone wants to read it.
The way to do a "words to look for" inside the regex is like this:
regex = #"(Key1|Key2|Key3|LastName|FirstName|Etc):"
What you are doing probably isn't worth the effort in a regex, though it can probably be done the way you want (still not 100% clear on requirements, though). It involves looking ahead to the next match, and stopping at that point.
Here is a re-write as a regex + regular functional code that should do the trick. It doesn't care about spaces, so if you ask for "Key2" like below, it will separate it from the value.
string[] keys = {"Key1", "Key2", "Key3"};
string source = "Key1:Value1Key2: ValueAnd A: To Test Key3: Something";
FindKeys(keys, source);
private void FindKeys(IEnumerable<string> keywords, string source) {
var found = new Dictionary<string, string>(10);
var keys = string.Join("|", keywords.ToArray());
var matches = Regex.Matches(source, #"(?<key>" + keys + "):",
RegexOptions.IgnoreCase);
foreach (Match m in matches) {
var key = m.Groups["key"].ToString();
var start = m.Index + m.Length;
var nx = m.NextMatch();
var end = (nx.Success ? nx.Index : source.Length);
found.Add(key, source.Substring(start, end - start));
}
foreach (var n in found) {
Console.WriteLine("Key={0}, Value={1}", n.Key, n.Value);
}
}
And the output from this is:
Key=Key1, Value=Value1
Key=Key2, Value= ValueAnd A: To Test
Key=Key3, Value= Something
/KeywordB\: (\w)/
This matches any word that comes after your keyword. As you didn´t mentioned any terminator, I assumed that you wanted only the word next to the keyword.