Reputation: 125
Lngton KY 40511 ARRIER — LEAVE IF NO RESPONSE LODRESS SERVICE REQUESTED
604159595920
YAWAR MUHAMMAD YOUNUS
1263 S CHILLICOTHE RD STE
AURORA OH 43192—8552 695—81
Basically what I want to do is to search for this : 0604156595920 (Some random number of length 12 which will be always above the customer name) and when the match is success then I want to get the next line as an output : YAWAR MUHAMMAD YOUNUS (Customer Name).
I am doing it like this because the pattern of the text will be different in each case, the line number will be different and obviously the customer name will be different also.
Here is my code :
using System.Text.RegularExpressions;
string strRegex = @"(?<=\d{12}\n)(\w.*)";
Regex myRegex = new Regex(strRegex, RegexOptions.IgnoreCase |RegexOptions.Multiline | RegexOptions.ExplicitCapture);
foreach (string line in File.ReadLines("SampleText.txt"))
{
Match match = myRegex.Match(line);
if (match.Success)
{
MessageBox.Show(match.Value);
}
else
{
MessageBox.Show("Fail");
}
}
This code works fine when the numbers and the name are in same line. But doesn't work for different line.
Another Regex which I tried :
(?<=(^\d{13}\n))[A-Za-z].*
The above regex works fine in an online regex tester.
Any help and suggestion will be appreciated. Thanks :) Sorry in advance if this is a repeated question. I searched alot on the web but couldn't find any specific answer to my problem.
EDIT : Screenshot of regexTester -> https://drive.google.com/open?id=0B6ynC-W5aF41cGhJREhtNGhHRnc
Upvotes: 2
Views: 2145
Reputation: 626950
You can use LINQ to get the line you need with:
var s = @"Lngton KY 40511 ARRIER — LEAVE IF NO RESPONSE LODRESS SERVICE REQUESTED
604159595920
YAWAR MUHAMMAD YOUNUS
1263 S CHILLICOTHE RD STE
AURORA OH 43192—8552 695—81";
var res = s.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) // Split into lines (you already have it)
.SkipWhile(p => !(p.Trim().Length == 12 && p.Trim().All(m => Char.IsDigit(m))))
.Skip(1)
.Take(1)
.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(res))
Console.WriteLine(res);
See the IDEONE demo
Just omit s
declaration and replace s.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)
in my code with your File.ReadLines("SampleText.txt")
.
Explanation:
s.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)
- splits the string into lines (you read the file into lines (just make sure there are no empty lines!)SkipWhile
- above skips all lines that are not 12 chars long (!(
p.Trim().Length == 12) and that are not all digits (
p.Trim().All(m => Char.IsDigit(m))`)Skip(1)
- skips the line with the 12-digit numberTake(1)
- just takes the current line (the one after the line with just 12-digit number)FirstOrDefault()
- gets the item as a string object or null if not found.var res = Regex.Match(s, @"^\p{Zs}*\d{12}\p{Zs}*(?:\r?\n)+(?<MYLINE>.*)", RegexOptions.Multiline);
if (res.Success)
Console.WriteLine(res.Groups["MYLINE"].Value);
If there can be a #
before then number, replace the regex with
@"^\p{Zs}*#?\d{12}\p{Zs}*(?:\r?\n)+(?<MYLINE>.*)"
^
It will match both 12 digits numbers with and without #
.
Explanation:
^
- start of a line (becuase RegexOptions.Multiline
redefines the ^
to match a line start rather than string start)\p{Zs}*
- 0+ horzontal spaces (so as not to jump to another line, can be replaced with [^\S\r\n]
to match all horizontal whitespace)#?
- one or zero #
\d{12}
- 12 digits\p{Zs}*
- see above(?:\r?\n)+
- 1 or more linebreaks (either CRLF or just LF style)(?<MYLINE>.*)
- Capture Group "MYLINE": any 0+ characters other than a newlineUpvotes: 1
Reputation: 73
string strRegex = @"\d{12}\s+(.+)\n$";
modifiers - Multiline
string s = File.ReadAllText(@"C:\Temp\SampleText.txt");
MatchCollection mc = Regex.Matches(s, @"\d{12}\s+(.+)\n", RegexOptions.Multiline);
foreach(var i in mc)
{
Match m = Regex.Match(i.ToString(), @"\s+(.+)*", RegexOptions.Multiline);
Console.WriteLine(m.Groups[1]);
}
Upvotes: 1