Regex string in IOS application - c#

I am trying to convert string which i take form NSDictionary as a dictionary and then I have to via method :
string NSDictionaryConverter(string name)
{
foreach (var a in str)
{
if (a.Key.Description.Equals(name))
{
result = a.Value.ToString();
}
Console.WriteLine(str.Keys);
}
return result;
}
Take what ever i need.
Why do I use dictionary ? These dictionary contains information for everything which conatain annotation from the map.
The Key FormattedAddressLines contatins for example :
FormattedAddressLines = (
"ZIP City Name",
Country
);
The value which with I have problems is address, because it contains a lot of details. I need all them displayed nicely on the screen.
Namely, I need to remove ", (, ) chars and line breaks with whitespace before punctuation.
After regex it looks still messy :
string address = NSDictionaryConverter("FormattedAddressLines");
string city = NSDictionaryConverter("City");
string zip = NSDictionaryConverter("ZIP");
string country = NSDictionaryConverter("Country");
address = Regex.Replace(address, #"([()""])+", "");
fullAddress = address + ", " + city + ", " + zip + ", " + country;
addressLabel.Text = fullAddress;
How could i do this to looks like :
Full Address value, - new line
XXX, - new line
XXX, - new Line
... - new line
N value - new line

It seems you need to remove specific special characters and whitespace before punctuation.
You need to add a \s*(?:\r?\n|\r)\s*(?=\p{P}) alternative to your regex:
Regex.Replace(address, #"[()""]+|\s*(?:\r?\n|\r)+\s*(?=\p{P})", "")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The \s* matches 0+ whitespaces, (?:\r?\n|\r)+ matches 1 or more line breaks and \s*(?=\p{P}) matches 0+ whitespaces that are followed with a punctuation symbol. It might be necessary to replace \p{P} with [\p{P}\p{S}] if you also want to include symbols.
See the regex demo:

Related

How to find and get string after a string known values in a text file c#

I want to find and get a string after a string known values in a text file with c#
My text file:
function PreloadFiles takes nothing returns nothing
call Preload( "=== Save ===" )
call Preload( "Player: Michael" )
call Preload( "-load1 UvjkiJyjLlPN1o7FCAwQ0en80t769u5uBKAL1t0u0Cajk86WNmp83F" )
call Preload( "-load2 IMdOIPKGSDFXStx4Zd4LAvAaBmHW19rxsvSNF6kaObSFyBzGq8skYGuq0T1eW" )
call Preload( "-load3 Bd6MoyqnfDydBbwqGApWii3mabJpwNvjcwrKLI0r6UU2wadrMV1h7WQ8D6" )
call Preload( "-load4 D5kI18Flk5bJ4Oi7vQw33b5LHDXHGgJNYsiC6VNJDAHe1" )
call Preload( "KEY PASS: 3568" )
endfunction
i want to get string after string "-load1" ,"-load2" ,"-load3" ,"-load4" ,"KEY PASS: " and fill them on 5 Textbox
like that
UvjkiJyjLlPN1o7FCAwQ0en80t769u5uBKAL1t0u0Cajk86WNmp83F
IMdOIPKGSDFXStx4Zd4LAvAaBmHW19rxsvSNF6kaObSFyBzGq8skYGuq0T1eW
Bd6MoyqnfDydBbwqGApWii3mabJpwNvjcwrKLI0r6UU2wadrMV1h7WQ8D6
D5kI18Flk5bJ4Oi7vQw33b5LHDXHGgJNYsiC6VNJDAHe1
3568
Please help me
Thanks you!
you can use
string Substring (int startIndex);
like:
string in1 = "-load1 UvjkiJyjLlPN1o7FCAwQ0en80t769u5uBKAL1t0u0Cajk86WNmp83F";
string out = in1.substring(7);
it returns:
"UvjkiJyjLlPN1o7FCAwQ0en80t769u5uBKAL1t0u0Cajk86WNmp83F"
It is possible to do with Regex class (from System.Text.RegularExpressions namespace).
Patterns examples:
for -loadN ... string: " [A-Za-z0-9]*\" ". It means Regex should look for substring which starts with whitespace " " contains some amount of chars (A-z) (of any case) or digits (0-9) and ends with double quote \" and whitespace " ". Such as yours UvjkiJyjLlP..." .
for KEY PASS: ... string: #"KEY PASS: (\d{4})". This means Regex should find a substring which contains "KEYPASS: " text and some string of 4 digits and with whitespace " " between them.
But aware, it's very unsafe, because Regex patterns is very sensitive.
For example,
"-loaddd1 AbCdEfG..." (extra chars)
"-load1 AbCdEfG..." (multiple whitespaces)
"KEY PASS: 12345" (pattern in example below looks strictly only for 4 digits, not 5 or more or less)
"-LOAD1 AbCdEfG..." (uppercased)
etc.
This ones will be ignored (last, btw, could be solved by passing RegexOptions.IgnoreCase into Regex.Match(line, pattern, RegexOptions.IgnoreCase)). Others could be solved too, but you should know that this cases are possible.
For a provided in question example this code works fine:
string loadPattern = " [A-Za-z0-9]*\" ";
string keyPassPattern = #"KEY PASS: (\d{4})";
List<string> capturedValues = new List<string>();
foreach (string line in File.ReadAllLines("Preload.txt"))
{
string s;
if (Regex.IsMatch(line, loadPattern) && line.Contains("-load"))
{
// Getting captured substring and trimming from trailing whitespace and quote
s = Regex.Match(line, loadPattern, RegexOptions.IgnoreCase).Value.Trim('\"', ' ');
capturedValues.Add(s);
}
else if (Regex.IsMatch(line, keyPassPattern))
{
// Just replacing "KEY PASS: " to empty string
s = Regex.Match(line, keyPassPattern).Value.Replace("KEY PASS: ", "");
capturedValues.Add(s);
}
}
Result:
string s1 = "-load1 UvjkiJyjLlPN1o7FCAwQ0en80t769u5uBKAL1t0u0Cajk86WNmp83F";
String filter = s1.ToString();
String[] filterRemove = filter.Split(' ');
String Value1= filterRemove[1];
In this way, you will get
"UvjkiJyjLlPN1o7FCAwQ0en80t769u5uBKAL1t0u0Cajk86WNmp83F" in value1
in the same way you can do for all the string and combine them.

Replace a part of string containing Password

Slightly similar to this question, I want to replace argv contents:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
to this:
"-help=none\n-URL=(default)\n-password=********\n-uname=Khanna\n-p=100"
I have tried very basic string find and search operations (using IndexOf, SubString etc.). I am looking for more elegant solution so as to replace this part of string:
-password=AnyPassword
to:
-password=*******
And keep other part of string intact. I am looking if String.Replace or Regex replace may help.
What I've tried (not much of error-checks):
var pwd_index = argv.IndexOf("--password=");
string converted;
if (pwd_index >= 0)
{
var leftPart = argv.Substring(0, pwd_index);
var pwdStr = argv.Substring(pwd_index);
var rightPart = pwdStr.Substring(pwdStr.IndexOf("\n") + 1);
converted = leftPart + "--password=********\n" + rightPart;
}
else
converted = argv;
Console.WriteLine(converted);
Solution
Similar to Rubens Farias' solution but a little bit more elegant:
string argv = "-help=none\n-URL=(default)\n-password=\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)[^\n]*", "$1********");
It matches password= literally, stores it in capture group $1 and the keeps matching until a \n is reached.
This yields a constant number of *'s, though. But telling how much characters a password has, might already convey too much information to hackers, anyway.
Working example: https://dotnetfiddle.net/xOFCyG
Regular expression breakdown
( // Store the following match in capture group $1.
password= // Match "password=" literally.
)
[ // Match one from a set of characters.
^ // Negate a set of characters (i.e., match anything not
// contained in the following set).
\n // The character set: consists only of the new line character.
]
* // Match the previously matched character 0 to n times.
This code replaces the password value by several "*" characters:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)([\s\S]*?\n)",
match => match.Groups[1].Value + new String('*', match.Groups[2].Value.Length - 1) + "\n");
You can also remove the new String() part and replace it by a string constant

Regex to group Zip Code , City and State

I have the following string
"98225-2077 Bellingham WA"
I need to use Regex to separate Zip Code, City and State.
the groups should return
(98225-2077)(Bellingham) and (WA).
The State is optional and will always be at the end and will consist of two Uppercase charachters.
I am able to filter out the following using regex
Zip Code : (^([\S]+-)?\d+(-\d+)?) - Group[1]
City: ((^([\S]+-)?\d+(-\d+)?)\s)?(\S.*) = Group[5].
Can there be a single regex to filter out all the three using the same regex and return blank in case the state is not there?
I would opt for just splitting the string on space and then using the various parts as you need. Because your city name may consist of multiple words, I iterate from the second to next-to-last element to build the city name. This solution assumes that the zip code and state two abbreviation will always be single words.
string address = "98225-2077 Bellingham WA";
string[] tokens = address.Split(' ');
string city = "";
for (int i=1; i < tokens.Length-1; i++)
{
if (i > 1)
{
city += " ";
}
city += tokens[i];
}
Console.WriteLine("zip code: {0}", tokens[0]);
Console.WriteLine("city: {0}", city);
Console.WriteLine("state: {0}", tokens[tokens.Length-1]);
Easy!
^([\d-]+)\s+(.+?)\s*([A-Z]{2})?$
https://regex101.com/r/tL4tN5/1
Explanation:
^([\d-]+): ^ is for the very beginning of the string. \d for digits
\s+(.+?)\s*: Get anything in the middle between ZIP code and state
([A-Z]{2})?$: {2} means 2 character in the specified range [A-Z]. ? means it exists 1 or 0 times.
This will also work
^(\d[\d-]+)\s+(.*?)(?:\s+([A-Z]{2}))?$
Regex Demo
Ideone Demo
I really think you can do it without a regex. Here are two solutions:
Non-regex solution:
/// <summary>
/// Split address into ZIP, Description/Street/anything, [A-Z]{2} state
/// </summary>
/// <returns>null if no space is found</returns>
public static List<string> SplitZipAnyStateAddress(this string s)
{
if (!s.Contains(' ')) return null;
var zip = s.Substring(0, s.IndexOf(' '));
var state = s.Substring(s.LastIndexOf(' ') + 1);
var middle = s.Substring(zip.Length + 1, s.Length - state.Length - zip.Length - 2);
return state.Length == 2 && state.All(p => Char.IsUpper(p)) ?
new List<string>() { zip, middle, state } :
new List<string>() { zip, string.Format("{0} {1}", middle, state) };
}
Results:
StringRegUtils.SplitZipAnyStateAddress("98225-2077 Bellingham WA");
// => [0] 98225-2077 [1] Bellingham [2] WA
StringRegUtils.SplitZipAnyStateAddress("98225-2077 Bellin gham");
// => [0] 98225-2077 [1] Bellin gham
StringRegUtils.SplitZipAnyStateAddress("98225-2077 New Delhi CA");
// => [0] 98225-2077 [1] New Delhi [2] CA
REGEX
If not, you can use my intial regex suggestion (I think a ? got lost):
^(?<zip>\d+-\d+)\s+(?<city>.*?)(?:\s+(?<state>[A-Z]{2}))?$
See the regex demo
Details:
^ - start of string
(?<zip>\d+-\d+) - 1+ digits followed with - followed with 1+ digits
\s+ - 1+ whitespaces
(?<city>.*?) - 0+ characters other than a newline as few as possible up to the
(?:\s+(?<state>[A-Z]{2}))? - optional (1 or 0) occurrences of
\s+ - 1+ whitespaces
(?<state>[A-Z]{2}) - exactly 2 uppercase ASCII letters
$ - end of string

Named group in regular expression match

I'm trying to parse some source files for some standard information.
The source files could look like this:
// Name: BoltBait
// Title: Some cool thing
or
// Name :
// Title : Another thing
or
// Title:
// Name:
etc.
The code I'm using to parse for the information looks like this:
Regex REName = new Regex(#"\/{2}\s*Name\s*:\s*(?<nlabel>.*)\n", RegexOptions.IgnoreCase);
Match mname = REName.Match(ScriptText); // entire source code file
if (mname.Success)
{
Name.Text = mname.Groups["nlabel"].Value.Trim();
}
Which works fine if the field has information. It doesn't work if the field is left blank.
For example, in the third example above, the Title field returns a match of "// Name:" and I want it to return the empty string.
I need help from a regex expert.
I thought the regex was too greedy, so I tried the following expression:
#"\/{2}\s*Name\s*:\s*(?<nlabel>.*?)\n"
However, it didn't help.
You can also use a class subtraction to avoid matching newline symbols:
//[\s-[\r\n]]*Name[\s-[\r\n]]*:[\s-[\r\n]]*(?<nlabel>.*)(?=\r?\n|$)
Note that:
[\s-[\r\n]]* - Matches any whitespace excluding newline symbols (a character class subtraction is used)
(?=\r?\n|$) - A positive look-ahead that checks if there is a line break or the end of the string.
See regex demo, output:
\s includes line breaks, which is not wanted here.
It should suffice to match tabs and spaces explicitly after :
\/{2}\s*Name\s*:[\t ]*(?<nlabel>.*?)\n
This returns the empty string correctly in your third example (for both name and title).
My approach is to use an alternate in a non-capturing group to match the label from the colon to the end of the line. This matches either anything to the end of the line, or nothing.
var text1 = "// Name: BoltBait" + Environment.NewLine + "// Title: Some cool thing" + Environment.NewLine;
var text2 = "// Name :" + Environment.NewLine + "// Title : Another thing" + Environment.NewLine;
var text3 = "// Title:" + Environment.NewLine + "// Name:" + Environment.NewLine;
var texts = new List<string>() { text1, text2, text3 };
var options = RegexOptions.IgnoreCase | RegexOptions.Multiline;
var regex = new Regex("^//\\s*?Name\\s*?:(?<nlabel>(?:.*$|$))", options );
foreach (var text in texts){
var match = regex.Match( text );
Console.WriteLine( "|" + match.Groups["nlabel"].Value.Trim() + "|" );
}
Produces:
|BoltBait|
||
||

Need to extract fields from a string in C#

I have extract the 3 usable field from a string. There is no common delimiter, there can be both blank spaces and tabs.
First, what I am doing is replacing all double blanks and tabs by '**'
Given String :
cont = Gallipelle 04/04/2012 16.03.03 5678
I am using:
cont.Replace(" ", "**").Replace(" ", "**").Replace(" ", "**").Replace("**", "").Trim()
The answer becomes:
****** Gallipelle******04/04/2012 16.03.03************************ 5678*****
Is the approach correct? How do I extract the stuffs from here? I just need all the extracts in string datatype.
Just use String.Split:
var fields = cont.Split(new[] { " ", "\t" },
StringSplitOptions.RemoveEmptyEntries);
Adding StringSplitOptions.RemoveEmptyEntries makes sure that if there are multiple consecutive tabs and/or spaces they will "count as one" when extracting the results.
An alternate option would be to use a regular expression.
You can use regex groups to find out three values name, date, number.
A group is defined as (?<group_name><regex_expr>)
So you could write
Regex regex = new Regex("(?<name>(\\S*))(\\s*)(?<date>((\\S*)\\s(\\S*)))(\\s*)(?<number>(\\d*))");
Match match = regex.Match(yourString);
if (match.Success)
{
string name = match.Groups["name"].Value;
string date = match.Groups["date"].Value;
string number = match.Groups["number"].Value;
}
\s* matches sequence of whitespaces which includes tabs.
\S* matches sequence of non-whitespace characters.
\d* matches sequence of digits.
(new Regex("\\s+")).Split(yourstring)
http://msdn.microsoft.com/en-us/library/8yttk7sy.aspx
var myText="cont = Gallipelle 04/04/2012 16.03.03 5678";
var splitString=myText.split(" ");
// splitString[1] == Gallipelle
// splitString[2] == 04/04/2012
// splitString[3] == 16.03.03
// splitString[4] == 5678
No. No need to replace it with any other delimiter. You can use String's split function and give 'space' as delimiter character. e.g. in VB.Net:
Dim value As String() = cont.split(CChar(" "))
this will give you a string array whose values you can access: value(0), value(1) and value(2)

Categories