Regex return bad string - c#

in string "<-6838.36,-6723.11,0,0> <-7091.07,-6554.64,133,0> <-368,-368,0,1> <-400,-432,0,1> <-336,-432,0,1> <-304,-368,0,1> "
pattern1 #"\<(.*?),(.*?),(.*?),0\>";
pattern2 #"\<(.*?),(.*?),(.*?),1\>";
result 1:"-6838.36" 2:"-6723.11" 3:"0,0> <-7091.07,-6554.64,133,0> <-368,-368,0"
need: 1:"-6838.36" 2:"-6723.11" 3:"0"
code:
string instring = "<-6838.36,-6723.11,0,0> <-7091.07,-6554.64,133,0> <-368,-368,0,1> <-400,-432,0,1> <-336,-432,0,1> <-304,-368,0,1> ";
string myteamheroes = #"\<(.*?),(.*?),(.*?),0\>";
string enemyheroes = #"\<(.*?),(.*?),(.*?),1\>";
MatchCollection collmytmheros = Regex.Matches(instring, myteamheroes);
MatchCollection collenemytmheros = Regex.Matches(instring, enemyheroes);
var us_EN = new CultureInfo("en-US");
foreach (Match herodata in collmytmheros)
{
String sX = herodata.Groups[1].Value;
String sY = herodata.Groups[2].Value;
String sR = herodata.Groups[3].Value;
double fX = float.Parse(sX, us_EN) + 7250.0d;
double fY = float.Parse(sY, us_EN) + 7950.0d;
int fR = int.Parse(sR);
// here error
//...other code
}
foreach (Match herodata in collenemytmheros)
{
String sX = herodata.Groups[1].Value;
String sY = herodata.Groups[2].Value;
String sR = herodata.Groups[3].Value;
// MessageBox.Show("1:\"" + sX +"\"2:\"" + sY + "?" + "\"3:\"" + "?");
double fX = float.Parse(sX, us_EN) + 7250.0d;
double fY = float.Parse(sY, us_EN) + 7950.0d;
int fR = int.Parse(sR);
// here error
//... other code
}
Did I wrote anything wrong?

Could try the following regular expressions to match the results:
Pattern 1
\<([-0-9.]+),([-0-9.]+),([-0-9.]+),0\>
Patter 2
\<([-0-9.]+),([-0-9.]+),([-0-9.]+),1\>

I'm not entirely sure I understand what you're doing, so a regex might not be the best way to go about parsing your data. That said, I think the problem you're having is that the (.*?),0\> section will run past the end of your small groups of <data>, and run into the next set to obtain a match.
If you're sure there are only going to be numbers in there, you can alter your regex to be more specific:
e.g <([\d-.]+),([\d-.]+),([\d-.]+),0> (with a 1 instead of the 0 for your 'enemies').

Related

C#, selecting certain parts from string

In my example I have a string: "POINT (6.5976512883340064 53.011505757047068)"
What I would like is to extract the two doubles from that string and place them in separate strings.
I could use a StringReader, however the doubles are not fixed in length (aka the length may vary) so I can't state after which position to start selecting.
What I would like is to state that the first selection be made after the "(" and before the whitespace, and the second selection be made after the white space and before the ")". The rest of the string can be ignored.
Any suggestions?
void GetDoubles()
{
string valuesWithoutBrackets = ExtractStringBetweenBrackets("POINT (6.5976512883340064 53.011505757047068)");
string[] values = valuesWithoutBrackets.Split(" ".ToCharArray());
//values[0] = "6.5976512883340064"
//values[1] = "53.011505757047068"
}
string ExtractStringBetweenBrackets(string s)
{
// You should check for errors in real-world code, omitted for brevity
var startTag = "(";
int startIndex = s.IndexOf(startTag) + startTag.Length;
int endIndex = s.IndexOf(")", startIndex);
return s.Substring(startIndex, endIndex - startIndex);
}
You can use the following code:
var str = "POINT (6.5976512883340064 53.011505757047068)";
var nums = Regex.Replace(a, #"POINT\s*\(([^)]+)\)", "$1").Split(' ');
var x = nums[0];
var y = nums[1];
var point = "POINT (6.5976512883340064 53.011505757047068)";
var indexOfFirstBrace = point.IndexOf('(') + 1;
var indexOfLastBrace = point.IndexOf(')');
var coordinates = point.Substring(indexOfFirstBrace, indexOfLastBrace - indexOfFirstBrace).Split(' ');
var xCoordinate = coordinates[0];
var yCoordinate = coordinates[1];

C# Regex for masking E-Mails

Is there a simple way for masking E-Mail addresses using Regular Expressions in C#?
My E-Mail:
myawesomeuser#there.com
My goal:
**awesome****#there.com (when 'awesome' was part of the pattern)
So it's more like an inverted replacement where evertyhing that does not actually match will be replaced with *.
Note: The domain should never be replaced!
From a performance side of view, would it make more sense to split by the # and only check the first part then put it back together afterwards?
Note: I don't want to check if the E-Mail is valid or not. It's just a simple inverted replacement and only for my current needs, the string is an E-Mail but for sure it can be any other string as well.
Solution
After reading the comments I ended up with an extension-method for strings which perfectly matches my needs.
public static string MaskEmail(this string eMail, string pattern)
{
var ix1 = eMail.IndexOf(pattern, StringComparison.Ordinal);
var ix2 = eMail.IndexOf('#');
// Corner case no-#
if (ix2 == -1)
{
ix2 = eMail.Length;
}
string result;
if (ix1 != -1 && ix1 < ix2)
{
result = new string('*', ix1) + pattern + new string('*', ix2 - ix1 - pattern.Length) + eMail.Substring(ix2);
}
else
{
// corner case no str found, all the pre-# is replaced
result = new string('*', ix2) + eMail.Substring(ix2);
}
return result;
}
which then can be called
string eMail = myawesomeuser#there.com;
string maskedMail = eMail.MaskEmail("awesome"); // **awesome****#there.com
string email = "myawesomeuser#there.com";
string str = "awesome";
string rx = "^((?!" + Regex.Escape(str) + "|#).)*|(?<!#.*)(?<=" + Regex.Escape(str) + ")((?!#).)*";
string email2 = Regex.Replace(email, rx, x => {
return new string('*', x.Length);
});
There are two sub-regular expressions here:
^((?!" + Regex.Escape(str) + "|#).)*
and
(?<!#.*)(?<=" + Regex.Escape(str) + ")((?!#).)*
They are in | (or)
The first one means: from the start of the string, any character but stop when you find str (escaped) or #
The second one means: there mustn't be a # before the start of this matching and, starting from str (escaped), replace any character stopping at the #
Probably faster/easier to read:
string email = "myawesomeuser#there.com";
string str = "awesome";
int ix1 = email.IndexOf(str);
int ix2 = email.IndexOf('#');
// Corner case no-#
if (ix2 == -1) {
ix2 = email.Length;
}
string email3;
if (ix1 != -1 && ix1 < ix2) {
email3 = new string('*', ix1) + str + new string('*', ix2 - ix1 - str.Length) + email.Substring(ix2);
} else {
// corner case no str found, all the pre-# is replaced
email3 = new string('*', ix2) + email.Substring(ix2);
}
This second version is better because it handle corner cases like: string not found and no domain in the email.
(awesome)|.(?=.*#)
Try this.Replace by *$1.But there will be an extra * at the start.So remove a * from the masked email from the start.See demo.
https://regex101.com/r/wU7sQ0/29
Non RE;
string name = "awesome";
int pat = email.IndexOf('#');
int pname = email.IndexOf(name);
if (pname < pat)
email = new String('*', pat - name.Length).Insert(pname, name) + email.Substring(pat);

Get string between Two dots c#

how can i get string between two dots for example ?
[Person.Position.Name]
for this case I want to get the string "Position"
I can also have three dots ….
[Person.Location.City.Name]
I want to take all strings between dots
I know it's a year old question, but the other answers are not sufficient, like they are even pretending that you want "Location.City" because they don't know how to seperate them.. The solution is simple though, don't use indexof.
say you want to seperate the Four (not 3) parts:
String input = "Person.Location.City.Name"
string person = input.Split('.')[0];
string location = input.Split('.')[1];
string city = input.Split('.')[2];
string name = input.Split('.')[3];
Console.WriteLine("Person: " + person + "\nLocation: " + location + "\nCity: " + city + "\nName: " + name);
This might help you:
string s = "Person.Position.Name";
int start = s.IndexOf(".") + 1;
int end = s.LastIndexOf(".");
string result = s.Substring(start, end - start);
It will return all the values between the first and the last dot.
If you don't want the result with dot between the strings, you can try this:
string s = "Person.Location.Name";
int start = s.IndexOf(".") + 1;
int end = s.LastIndexOf(".");
var result = s.Substring(start, end - start).Split('.');
foreach (var item in result)
{
//item is some string between the first and the last dot.
//in this case "Location"
}
Try this
string str = "[Person.Location.City.Name]";
int dotFirstIndex = str.IndexOf('.');
int dotLastIndex = str.LastIndexOf('.');
string result = str.Substring((dotFirstIndex + 1), (dotLastIndex - dotFirstIndex) - 1); // output Location.City

strip out digits or letters at the most right of a string

I have a file name: kjrjh20111103-BATCH2242_20111113-091337.txt
I only need 091337, not the txt or the - how can I achieve that. It does not have to be 6 numbers it could be more or less but will always be after "-" and the last ones before ."doc" or ."txt"
You can either do this with a regex, or with simple string operations. For the latter:
int lastDash = text.LastIndexOf('-');
string afterDash = text.Substring(lastDash + 1);
int dot = afterDash.IndexOf('.');
string data = dot == -1 ? afterDash : afterDash.Substring(0, dot);
Personally I find this easier to understand and verify than a regular expression, but your mileage may vary.
String fileName = kjrjh20111103-BATCH2242_20111113-091337.txt;
String[] splitString = fileName.Split ( new char[] { '-', '.' } );
String Number = splitString[2];
Regex: .*-(?<num>[0-9]*). should do the job. num capture group contains your string.
The Regex would be:
string fileName = "kjrjh20111103-BATCH2242_20111113-091337.txt";
string fileMatch = Regex.Match(fileName, "(?<=-)\d+", RegexOptions.IgnoreCase).Value;
String fileName = "kjrjh20111103-BATCH2242_20111113-091337.txt";
var startIndex = fileName.LastIndexOf('-') + 1;
var length = fileName.LastIndexOf('.') - startIndex;
var output = fileName.Substring(startIndex, length);

How might I reformulate a "MM/YYYY" date as "YYYYMM"?

I want to convert this string format:
11/2013
TO
201311
So, suppose my string is in this variable:
string s = "11/2013";
What should be the code for this problem? Thanks!
sprime = s.Split(new char [] {'/'});
s = sprime[1] + sprime[0];
This is fastest:
s = s[3] + s[4] + s[5] + s[6] + s[0] + s[1];
If you are converting a gazillion billion records it will matter.
string newString = s.Split('/')[1] + s.Split('/')[0];
string [] split = s.Split('/');
string str = split[1] + split[0];
string s = "11/2011";
s = String.Format("{0}{1}", s.Split('/')[1], s.Split('/')[0]);
Note that this answer assumes s will match, and it will return an empty string if it doesn't.
Using Split will throw an IndexOutOfRangeException when you try to access [1] when there was no /.
You could of course add code to handle these cases regardless of whether you use Regex or Split.
string s = "11/2013";
// Match 1+ digits followed by a forward slash followed by 1+ digits
Regex r = new Regex(#"(\d+)/(\d+)");
var m = r.Match(s);
string result = m.Groups[2].Value + m.Groups[1].Value;
All so complicated. Makes my head hurt. Try this instead:
static readonly Regex rx = new Regex( #"^(\d\d)/(\d\d\d\d)$" ) ;
...
string s1 = "12/3456" ;
string s2 = rx.Replace( s1 , #"$2/$1" ) ;
Or Splitless for [??]/YYYY; s.Substring(s.Length - 4, 4) + s.Substring(0, s.Length - 5);
string s = "11/2013";
Regex r = new Regex("^(?<month>[0-1]?[0-9])/(?<year>[0-9]{4})$");
var match = r.Match(s);
string month = match.Groups["month"].Value;
string year = match.Groups["year"].Value;
string result = year + month;

Categories

Resources