I have a string "region_2>0" where I want to replace _2 with string.empty using Regex.
My expression is ((_)[^_]*)\w(?=[\s=!><]) which in both Regulator and Expresso gives me _2. However, the code(c#):
Regex.Match(legacyExpression, "((_)[^_]*)\\w(?=[\\s=!><])").Value
gives me "_2>0", which also causes the replace to be wrong (It returns "region" since removing the whole "_2>0" instead of "_2". The result I want is "region>0". Shouldn't the code and the regex programs give the same results? And how can I get it to work?
(Note the string is not static, it could be in many different forms, but the rule is I want to replace the last _X in the string with string.empty.
Thanks!
I copied your code as is into the new project:
static void Main(string[] args)
{
var legacyExpression = "region_2>0";
var rex = Regex.Match(legacyExpression, "((_)[^_]*)\\w(?=[\\s=!><])").Value;
Console.WriteLine(rex);
Console.ReadKey();
}
The output is _2.
I think this could work
(_\d+)
Related
Is it possible to do a string interpolation formatting a substring of a string?
I have been searching the Microsoft documents about string interpolation but cannot get a working sample done. reference.
Currently I have :
var description = "the quick brown fox";
var result = $"{description.Substring(0, description.Length < 10 ? description.Length : 10)} jumps..",
using string interpolation I would ideally like to use:
var description = "the quick brown fox";
var result = $"{description:10} jumps..",
editted
I would expect the output of result to be :
The quick jumps..
You can use ranges (C# 8):
var description = "the quick brown fox";
var result = $"{description[..10]} jumps..";
You can use Take method:
description.Take(10)
Unfortunately, this method returns IEnumerable which cannot be directly converted to string (ToString method would return name of type as usually when using it on IEnumerable).
You can't create string using it, because string constructor requires array of chars, so the easiest solution will be:
new string(description.Take(10).ToArray())
Still, such code makes it harder to read if you want to use it few times, so you can create extension method:
public static string TakeFirst(this string text, int number)
{
if (text == null)
return null;
return new string(text.Take(number).ToArray());
}
Then you can just use it:
$"{description.TakeFirst(10)} jumps..";
EDIT: As mentioned in comments, because of allocation of array each time this method is called, there might occur serious performance issues. You can avoid them by implementing TakeFirst method using Substring instead of Take(x).ToArray() solution.
As the question was:
"Is it possible to do a string interpolation formatting a substring of a string?"
In such a manner:
var result = $"{description:10} jumps..",
The answer given from #JohnSkeet and #JeroenMostert was most acurate:
"No, it is not possible."
There are various ways to simplify the call. thanks for #PiotrWojsa for pointing that out. however that doesnt involve the interpolation part..
How do I check a string to make sure it contains numbers, letters, or space only?
In C# this is simple:
private bool HasSpecialChars(string yourString)
{
return yourString.Any(ch => ! char.IsLetterOrDigit(ch));
}
The easiest way it to use a regular expression:
Regular Expression for alphanumeric and underscores
Using regular expressions in .net:
http://www.regular-expressions.info/dotnet.html
MSDN Regular Expression
Regex.IsMatch
var regexItem = new Regex("^[a-zA-Z0-9 ]*$");
if(regexItem.IsMatch(YOUR_STRING)){..}
string s = #"$KUH% I*$)OFNlkfn$";
var withoutSpecial = new string(s.Where(c => Char.IsLetterOrDigit(c)
|| Char.IsWhiteSpace(c)).ToArray());
if (s != withoutSpecial)
{
Console.WriteLine("String contains special chars");
}
Try this way.
public static bool hasSpecialChar(string input)
{
string specialChar = #"\|!#$%&/()=?»«#£§€{}.-;'<>_,";
foreach (var item in specialChar)
{
if (input.Contains(item)) return true;
}
return false;
}
String test_string = "tesintg#$234524##";
if (System.Text.RegularExpressions.Regex.IsMatch(test_string, "^[a-zA-Z0-9\x20]+$"))
{
// Good-to-go
}
An example can be found here: http://ideone.com/B1HxA
If the list of acceptable characters is pretty small, you can use a regular expression like this:
Regex.IsMatch(items, "[a-z0-9 ]+", RegexOptions.IgnoreCase);
The regular expression used here looks for any character from a-z and 0-9 including a space (what's inside the square brackets []), that there is one or more of these characters (the + sign--you can use a * for 0 or more). The final option tells the regex parser to ignore case.
This will fail on anything that is not a letter, number, or space. To add more characters to the blessed list, add it inside the square brackets.
Use the regular Expression below in to validate a string to make sure it contains numbers, letters, or space only:
[a-zA-Z0-9 ]
You could do it with a bool. I've been learning recently and found I could do it this way. In this example, I'm checking a user's input to the console:
using System;
using System.Linq;
namespace CheckStringContent
{
class Program
{
static void Main(string[] args)
{
//Get a password to check
Console.WriteLine("Please input a Password: ");
string userPassword = Console.ReadLine();
//Check the string
bool symbolCheck = userPassword.Any(p => !char.IsLetterOrDigit(p));
//Write results to console
Console.WriteLine($"Symbols are present: {symbolCheck}");
}
}
}
This returns 'True' if special chars (symbolCheck) are present in the string, and 'False' if not present.
A great way using C# and Linq here:
public static bool HasSpecialCharacter(this string s)
{
foreach (var c in s)
{
if(!char.IsLetterOrDigit(c))
{
return true;
}
}
return false;
}
And access it like this:
myString.HasSpecialCharacter();
private bool isMatch(string strValue,string specialChars)
{
return specialChars.Where(x => strValue.Contains(x)).Any();
}
Create a method and call it hasSpecialChar with one parameter
and use foreach to check every single character in the textbox, add as many characters as you want in the array, in my case i just used ) and ( to prevent sql injection .
public void hasSpecialChar(string input)
{
char[] specialChar = {'(',')'};
foreach (char item in specialChar)
{
if (input.Contains(item)) MessageBox.Show("it contains");
}
}
in your button click evenement or you click btn double time like that :
private void button1_Click(object sender, EventArgs e)
{
hasSpecialChar(textbox1.Text);
}
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the [https://www.nuget.org/packages/Extensions.cs][1] package to your project.
Add "using Extensions;" to the top of your code.
"smith23#".IsAlphaNumeric() will return False whereas "smith23".IsAlphaNumeric() will return True. By default the .IsAlphaNumeric() method ignores spaces, but it can also be overridden such that "smith 23".IsAlphaNumeric(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphaNumeric().
Based on #prmph's answer, it can be even more simplified (omitting the variable, using overload resolution):
yourString.Any(char.IsLetterOrDigit);
No special characters or empty string except hyphen
^[a-zA-Z0-9-]+$
I have an issue with a string containing the plus sign (+).
I want to split that string (or if there is some other way to solve my problem)
string ColumnPlusLevel = "+-J10+-J10+-J10+-J10+-J10";
string strpluslevel = "";
strpluslevel = ColumnPlusLevel;
string[] strpluslevel_lines = Regex.Split(strpluslevel, "+");
foreach (string line in strpluslevel_lines)
{
MessageBox.Show(line);
strpluslevel_summa = strpluslevel_summa + line;
}
MessageBox.Show(strpluslevel_summa, "summa sumarum");
The MessageBox is for my testing purpose.
Now... The ColumnPlusLevel string can have very varied entry but it is always a repeated pattern starting with the plus sign.
i.e. "+MJ+MJ+MJ" or "+PPL14.1+PPL14.1+PPL14.1" as examples.
(It comes form Another software and I cant edit the output from that software)
How can I find out what that pattern is that is being repeated?
That in this exampels is the +-J10 or +MJ or +PPL14.1
In my case above I have tested it by using only a MessageBox to show the result but I want the repeated pattering stored in a string later on.
Maybe im doing it wrong by using Split, maybe there is another solution.
Maybe I use Split in the wrong way.
Hope you understand my problem and the result I want.
Thanks for any advice.
/Tomas
How can I find out what that pattern is that is being repeated?
Maybe i didn't understand the requirement fully, but isn't it easy as:
string[] tokens = ColumnPlusLevel.Split(new[]{'+'}, StringSplitOptions.RemoveEmptyEntries);
string first = tokens[0];
bool repeatingPattern = tokens.Skip(1).All(s => s == first);
If repeatingPattern is true you know that the pattern itself is first.
Can you maybe explain how the logic works
The line which contains tokens.Skip(1) is a LINQ query, so you need to add using System.Linq at the top of your code file. Since tokens is a string[] which implements IEnumerable<string> you can use any LINQ (extension-)method. Enumerable.Skip(1) will skip the first because i have already stored that in a variable and i want to know if all others are same. Therefore i use All which returns false as soon as one item doesn't match the condition(so one string is different to the first). If all are same you know that there is a repeating pattern which is already stored in the variable first.
You should use String.Split function :
string pattern = ColumnPlusLevel.Split("+")[0];
...but it is always a repeated pattern starting with the plus sign.
Why do you even need String.Split() here if the pattern always only repeats itself?
string input = #"+MJ+MJ+MJ";
int indexOfSecondPlus = input.IndexOf('+', 1);
string pattern = input.Remove(indexOfSecondPlus, input.Length - indexOfSecondPlus);
//pattern is now "+MJ"
No need of string split, no need to use LinQ
String has a method called Split which let's you split/divide the string based on a given character/character-set:
string givenString = "+-J10+-J10+-J10+-J10+-J10"'
string SplittedString = givenString.Split("+")[0] ///Here + is the character based on which the string would be splitted and 0 is the index number
string result = SplittedString.Replace("-","") //The mothod REPLACE replaces the given string with a targeted string,i added this so that you can get the numbers only from the string
I want to be able to use the contains function the same way the like operator works in sql. So when I call .contains(%This%%%%%%is%%my%string%%) from a list or whatever such as "This is my string " then the function will return true. I've done a lot of searching and it seems like a lot of people would like this function. So how can this be done or how can a custom like function with the same functionality be made?
EDIT
Thank you, for the quick response. I was able to use a regular expressions inside of my own custom Like function. Below is the code for anyone else who wants to use something similar to SQL Like. In this code the user would input the databaze value and then spaces in that value are replaced with .* to ignore anything in-between the values.Just like using the % to replace spaces and values in SQL. I can then use .Like on my string value called testValue that I am searching through to return true or false depending on if the words or whatever are in my string. I also added ToUpper to ignore the case.
//C# Like function
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace sqllinqstuff
{
class Program
{
static void Main(string[] args)
{
string testValue = "Big RED Car";
string databaze = "big red CAR";
string databaze3 = databaze.Replace(" ", ".*");
databaze3 = databaze3.Replace(" ", ".*");
Console.WriteLine(databaze3);
Console.WriteLine(testValue.Like(databaze3));
Console.Read();
}
}
public static class CaseyStringExtension
{
public static bool Like(this string str,string value)
{
if (!string.IsNullOrEmpty(str))
{
Regex r = new Regex(value.ToUpper());
if (r.IsMatch(str.ToUpper()))
return true;
}
return false;
}
}
}
The result of this test will be true.
The way this would be done is with Regex. The syntax is not the same as a SQL LIKE query so there will be a bit of a learning curve. This is a good tutorial site I often reference, it can get you started with the basics.
Translating your original string you asked about, the regex search pattern would be
.*This.*is.*my.*string.*
Once you get good at it you can do searches like this one I helped create for a password complexity checker
(?=^.{8,}$)(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_])(?=^.*[^\s].*$).*$
The above search looks for a string that has at least 8 characters with at least one lower case letter, one upper case letter, one special character, and no white-space characters.
I am working on writing a method to remove the namespace from a System.Type.FullName (not XML).
I started off googling and didn't get too far so switched to trying to write a Regex I could use with a Regex.Replace(). But I am far from a master of the Regex arts, so I present myself humbly before the regex gods.
Given the following inputs:
name.space.class
name.space.class<other.name.space.class1>
name.space.class<other.name.space.class1, shortSpace.class2>
I need to remove the namespaces so I get:
class
class<class1>
class<class1, class2>
Alternatively, if anyone knows of an existing library that has this functionality, all the better!
Note: I know System.Type has a Namespace property that I could use to remove the namespace (ie System.Type.FullName - System.Type.Namespace), but my method takes a type name as a string and needs to work with type names that the run-time does not know about (can't resolve).
How about this...
[.\w]+\.(\w+)
...and substiuting with $1. See it in action on regex101.
From looking at some C# examples it seems you would do
string output = Regex.Replace(input, #"[.\w]+\.(\w+)", "$1");
Try this:
public static string RemoveNamespaces(string typename)
{
return string.Join("",
Regex.Split(typename,
#"([^\w\.])").Select(p =>
p.Substring(p.LastIndexOf('.') + 1)));
}
I wouldn't even consider using regexes for this. Imperative code is pretty trivial here, although it requires a bit of string-fu:
public string RemoveNamespace(string typename)
{
if(typename.Contains("<")
{
var genericArguments =
typename.
// in reality, we need a substring before
// first occurence of "<" and last occurence of ">"
SubstringBetween("<", ">").
Split(',').
Select(string.Trim).
Select(RemoveNamespace);
return
RemoveNamespace(typename.SubstringBefore("<")) +
"<" +
string.Join(", ", genericArguments) +
">";
}
else
{
return typename.Trim().SubstringAfterLastOccurenceOf(".");
}
}
Sounds like a good situation to use positive lookahead:
(\w+[.+])+(?=\w+)
This pattern will match any number of words separated by periods or plusses, except the last one in a sequence (the short name of the type). Replacing the matches by the empty string will remove all namespace prefixes.
Why not split by dot(.) and take only the last string