Using RegularExpression for Getting Parts of IP and Port Numbers - c#

I am trying to use Regular Expression in C# Visual Studio 2013, I need to get a string that looks like this 192.168.1.254:65.
What I need to do is break this string into two values an IP Address and a Port number, Everything to the left of the colon is going to be the IP Address and Everything to the right of the colon is going to be the port, I need to do this with a regular expression in C# Code. So please place any namespaces that need to be added in the code to use the regular expression in C#, Example below
string mystring = "192.168.1.254:65";
string myipaddress = RegularExpressionMethod(ExpressionToGetIp, mystring);
string myportnumber = RegularExpressionMethod(ExpressionToGetPort, mystring);
This has nothing to do with IPEndPoints its a general abstraction method

Just use the .Split() method:
string mystring = "192.168.1.254:65";
string[] s = mystring.Split(':');
string ip = s[0]; // "192.168.1.254"
string port = s[1]; // "65"
If you need to double check the IP and Port numbers are in the right format, you can add the System.Net; namespace, then parse each string:
try
{
IPAddress IP = IPAddress.Parse(ip);
int PortNum = Int32.Parse(port);
}
catch
{
// catch any exceptions here
}
Or a simpler method might be (courtesy of EZI for reminding me) using the .TryParse() method. This is a bit easier to deal with, as this outputs a bool.
IPAddress IP;
int PortNum;
if (IPAddress.TryParse(s[0], out IP)) // If it is a valid IP
{ MessageBox.Show("IP address in correct format"); }
else { MessageBox.Show("IP address not in correct format"); }
if (Int32.TryParse(s[1], out PortNum)) // If it is a valid Port Number
{ MessageBox.Show("Port Number in correct format"); }
else { MessageBox.Show("Port Number not in correct format"); }

You could not reinvent the wheel and say something like this:
string myString = "192.168.1.254:65";
UriBuilder uri = new UriBuilder("http://" + myString );
string host = uri.Host ;
int port = uri.Port ;
You could simply say:
string[] parts = myString.Split(":");
string host = parts[0] ;
string port = parts[1] ;
But you should be aware that this will break if you get IPv6 address literals.
You could use a regular expression:
Regex rx = new Regex( #"^(?<host>.+):(?<port>\d+)$");
Match m = rx.Match(myString);
if ( !m.Success ) throw new FormatException() ;
string host = m.Groups["host"].Value ;
int port = int.Parse( m.Groups["port"].Value ) ;
Or you could get all fancy-like and write an extension method:
static class ExtensionMethods
{
public static DnsEndPoint ToDnsEndpoint( this string text)
{
Match m = rxDnsEndpoint.Match(text);
if ( !m.Success ) throw new FormatException("invalid endpoint format");
string host = m.Groups["host"].Value ;
int port = int.Parse( m.Groups["port"].Value ) ;
IPAddress address ;
bool parsed = IPAddress.TryParse( host , out address ) ;
AddressFamily family = parsed ? address.AddressFamily : AddressFamily.Unspecified ;
DnsEndPoint endpoint = new DnsEndPoint( host , port , family ) ;
return endpoint;
}
private static Regex rxDnsEndpoint = new Regex( #"^(?<host>.+):(?<port>\d+)$");
}
Which lets you say things like
DnsEndpoint endpoint = myString.ToDnsEndpoint() ;

Related

Regex to validate multiple email addresses

I have tried this code to validate multiple email addresses:
string email = "kamilar#recruit12.com; test#minh.com; test2#yahoo.com";
REGEX_EMAIL_ADDRESS_MULTI = #"^\s*([a-zA-Z0-9_%+~=$&*!#?\-\'](\.)?)*[a-zA-Z0-9_%+~=$&*!#?\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*((,|;)\s*([a-zA-Z0-9_%+~=$&*!#?\-\'](\.)?)*[a-zA-Z0-9_%+~=$&*!#?\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*)*$";
Regex reg = new Regex(REGEX_EMAIL_ADDRESS_MULTI);
var isOk = reg.IsMatch(email);
But it does not match - why?
Note that it matches with single address with this following expression:
#"^\s*([a-zA-Z0-9_%\-\'](\.)?)*[a-zA-Z0-9_%\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*$"
Any help?
UPDATED:
I do NOT want to split the string to validate one by one! That's why I need to ask on Stack Overflow!
As others have noted, you should be validating them one at a time.
string email = "kamilar#recruit12.com; test#minh.com; test2#yahoo.com";
string[] emailAddresses = email.Split(';').Select(x=>x.Trim()).ToArray();
string REGEX_EMAIL_ADDRESS_MULTI = #"^\s*([a-zA-Z0-9_%+~=$&*!#?\-\'](\.)?)*[a-zA-Z0-9_%+~=$&*!#?\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*((,|;)\s*([a-zA-Z0-9_%+~=$&*!#?\-\'](\.)?)*[a-zA-Z0-9_%+~=$&*!#?\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*)*$";
bool isOk = true;
foreach (string emailAddress in emailAddresses)
{
Regex reg = new Regex(REGEX_EMAIL_ADDRESS_MULTI);
if (!reg.IsMatch(email))
{
isOk = false;
break;
}
}
split the string at the ';'
string email = "kamilar#recruit12.com; test#minh.com; test2#yahoo.com";
string[] emails = email.Split(';');
then create a method that returns the validity
private bool CheckAddress(string address){
REGEX_EMAIL_ADDRESS_MULTI = #"^\s*([a-zA-Z0-9_%+~=$&*!#?\-\'](\.)?)*[a-zA-Z0-9_%+~=$&*!#?\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*((,|;)\s*([a-zA-Z0-9_%+~=$&*!#?\-\'](\.)?)*[a-zA-Z0-9_%+~=$&*!#?\-\']#([a-zA-Z0-9-](\.)?)+[a-zA-Z]{2,6}(\.[a-zA-Z]{2,6})+\s*)*$";
Regex reg = new Regex(REGEX_EMAIL_ADDRESS_MULTI);
return reg.IsMatch(email);
}
now just loop through the addresses
for(int i = 0; i > emails.Length; i++){
var isOK = CheckAddress(emails[i]);
}
This address is bad an invalidates the address string
These addresses are OK and the string is allowed
It is my fault as the first email address does not passed the single email regex test so the multiple email regex test should fail.
Thanks.

How to Get system IP (IPv4) address and convert to string using C# asp.net

On my web application I am using the following function to get System IP
Function
public void SetHostid()
{
try
{
string ip = "";
string strHostName = "";
strHostName = System.Net.Dns.GetHostName();
IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
ip = addr[1].MapToIPv4().ToString();
HostId = ip;
HttpContext.Current.Session["Hostid"] = HostId;
}
catch (Exception ex)
{
Error_ManagerClass em = new Error_ManagerClass();
em.WriteError(ex);
}
}
It works perfectly because the IP is on the 1 postion of the variable addr (addr[ 1]).
And the problem comes when I try to run the same solution from a different system. function throws an error while trynig to convert IP to string( ip = addr[1].MapToIPv4().ToString(); ) because IP is not in the position number 1.
how can I change the function to work on every computer ??
If you want to get IPv4 only use this code:
var addr = ipEntry.AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork);
var firstInList = addr.First(); // get first
But you should consider which IP to chose when there are several IP addresses in system.

Get host from email string .net core

I need to get the host from an email address string.
In .net 4.x I did this
var email1 = "test#test.com";
var email2 = "test2#yea.test.com"
var email1Host = new MailAddress(email1).Host;
var email2Host = new MailAddress(email2).Host;
email1Host prints "test.com"
email2Host prints "yea.test.com"
But now i need only the "test.com" part in both examples.
.Net Standard library 1.6 doesnt have the System.Net.Mail class so I can't do this anymore.
Whats another way of accomplishing the same thing in .net core but I only need the test.com part
I know there is a System.Net.Mail-netcore nuget package, but I really want to avoid installing a nuget just for this
Edit: Sorry for the confusion I forgot to mention that I only need the test.com
More examples were requested
#subdomain1.domain.co.uk => domain.co.uk
#subdomain1.subdomain2.domain.co.uk => domain.co.uk
#subdomain1.subdomain2.domain.com => domain.com
#domain.co.uk => domain.co.uk
#domain.com => domain.com
Using String Split and Regex,
var email1 = "test#test.com";
var email2 = "test2#yea.test.co.uk";
var email1Host = email1.Split('#')[1];
var email2Host = email2.Split('#')[1];
Regex regex = new Regex(#"[^.]*\.[^.]{2,3}(?:\.[^.]{2,3})?$");
Match match = regex.Match(email1Host);
if (match.Success)
{
Console.WriteLine("Email Host1: "+match.Value);
}
match = regex.Match(email2Host);
if (match.Success)
{
Console.WriteLine("Email Host2: "+match.Value);
}
Update: Using regex to get the Domain name
An alternative is to use the System.Uri class and prefix the email with 'mailto'.
class Program
{
static void Main(string[] args)
{
string email = "test#test.com";
string emailTwo = "test2#subdomain.host.com";
Uri uri = new Uri($"mailto:{email}");
Uri uriTwo = new Uri($"mailto:{emailTwo}");
string emailOneHost = uri.Host;
string emailTwoHost = uriTwo.Host;
Console.WriteLine(emailOneHost); // test.com
Console.WriteLine(emailTwoHost); // subdomain.host.com
Console.ReadKey();
}
}
Well, a bit of C# should do the trick:
string email = "test#test.com";
int indexOfAt = email.IndexOf('#');
//You do need to check the index is within the string
if (indexOfAt >= 0 && indexOfAt < email.Length - 1)
{
string host = email.Substring(indexOfAt + 1);
}

Get value from a list and work with it

I am trying to build an application sends emails by socks, messages will be sent per message if the first message is sent through a socks, the second should use a different socks, what I do in my application if I as I Recuper the information from a txt file and I add to list :
try
{
SmtpServer oServer = new SmtpServer("");
var list = new List<string>();
var input = File.ReadAllText(#"C:\New folder\SendMail6\socks-list.txt");
var r = new Regex(#"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})");
foreach (Match match in r.Matches(input))
{
string ip = match.Groups[1].Value;
string port = match.Groups[2].Value;
list.Add(ip);
list.Add(port);
}
foreach (string ip in list)
{
}
}
catch(Exception)
{
}
what I want that
oServer.SocksProxyServer = "37.187.118.174";
oServer.SocksProxyPort = 14115;
takes the values from the list I completed by ip values and port, and
if the first mail is sent by an ip the second mail is use another ip in list dont send tow email which follow by same ip
Thanks
You need to create a class for IP and Port
public class IpAndPort
{
public string IpAddress { get; set; }
public string Port { get; set; }
}
Now use ConcurrentBag
using System.Collections.Concurrent;
//------
var ips = new ConcurrentBag<IpAndPort>();
var input = File.ReadAllText(#"C:\New folder\SendMail6\socks-list.txt");
var r = new Regex(#"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})");
foreach (Match match in r.Matches(input))
{
string ip = match.Groups[1].Value;
string port = match.Groups[2].Value;
if(ips.Any(x => x.IpAddress.Trim() == ip.Trim()))
continue;
ips.Add(new IpAndPort { IpAddress = ip, Port = port});
}
Now send message by taking values from ConcurrentBag
while (!ips.IsEmpty)
{
IpAndPort ipAndPort;
if (!ips.TryTake(out ipAndPort)) continue;
try
{
//code here to send message using below IP and Port
var ip = ipAndPort.IpAddress;
var port = ipAndPort.Port;
/----
oServer = new SmtpServer("");
oServer.SocksProxyServer = ip;
oServer.SocksProxyPort = port;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

Converting IPAddress[] to string

I've got a server application which I'm trying to automatically set the IP address to, taken from the machine's dynamically allocated IP address. So far I've got this to get the IPv4 but it's returned as type IPAddress[] which I have some trouble converting to a string[] so my HttpListener can use it. Any hint to how I can convert it? Or am I going about this the wrong way?
This is what I'm using to get the IP address:
class Program
{
static void Main(string[] args)
{
string name = (args.Length < 1) ? Dns.GetHostName() : args[0];
try
{
IPAddress[] addrs = Array.FindAll(Dns.GetHostEntry(string.Empty).AddressList,
a => a.AddressFamily == AddressFamily.InterNetwork);
Console.WriteLine("Your IP address is: ");
foreach (IPAddress addr in addrs)
Console.WriteLine("{0} {1}", name, addr);
//Here I'm trying to convert the IPAddress[] into a string[] to use in my listener
string str = addrs.ToString();
string[] ipString = { str };
Response.Listener(ipString);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//current way of setting the IP address - not optimal
string[] ipstring = new string[1] {"10.10.180.11:8080"};
Response.Listener(ipstring);
}
}
And the listener for good times sake:
public static void Listener(string[] prefixes)
{
if (!HttpListener.IsSupported)
{
Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
return;
}
// URI prefixes are required,
// for example "http://contoso.com:8080/index/".
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
// Create a listener.
HttpListener listener = new HttpListener();
// Add the prefixes.
foreach (string s in prefixes)
{
listener.Prefixes.Add("http://" + s + "/");
}
listener.Start();
This should do the trick.
string[] ips = addresses.Select(ip => ip.ToString()).ToArray();
Make sure you have a using statement for System.Linq
You are trying to convert an IPAdress's array like one IPAdress.
You can use LINQ to convert each IPAdress, then you can make the String's array :
String[] strAddrs = (from cad in addrs select cad.ToString()).ToArray();
Don't forget : using System.Linq;
If you have an IPAddress object, you can get the string representation like this:
v4:
validIP4.MapToIPv4().ToString();
v6:
validIP4.MapToIPv6().ToString();

Categories