C# - Read between parentheses in RichTextBox - c#

So I want to find out what is in between specific parentheses in a richtextbox. For example:
if (richTextBox1.Text.Contains("testname(") {
// Find what is in brackets of testname()
String outcome = //what is in brackets of testname()
}
This may be hard to understand, but let's say this is the richtextbox:
testname(name)
Then the string outcome would be name.

You can use regular expression to get the value between the parenthesis.
string text = richTextBox1.Text; // testname("some text")
string value = Regex.Match(text, #"\(([^)]*)\)").Groups[1].Value;

wrote from iPad so not tested, but something along these lines should get you there
String a = "testname(";
String b = "testname(Val)";
int x = b.IndexOf(a);
If (richTextBox1.Text.Contains(a)){
if (x != -1)
{
string final = b.Substring(x + a.Length);
}
}

string outcome = richTextBox1.Text;
outcome = outcome.Substring(outcome.IndexOf("(")+1, outcome.IndexOf(")") - outcome.IndexOf("("));

Regex would be the way to go.
Here I am matching exactly a parenthesis followed by any character one or more times followed by another parenthesis.
You have to escape parenthesis.
string yourText = richTextBox1.Text;
//string cow = "this is some text(this is the text you want)";
Regex regex = new Regex(#"\(.+\)");
Match match = regex.Match(yourText);
if (match.Success)
{
Console.WriteLine(match.Value); // with cow -> this is the text you want
} // can have else
You may want to consider using * instead of + in case they don't have any input between the ( ) Example: Regex regex = new Regex(#"\(.*\)");
Now it matches any character 0 or more times

You can achieve this with Linq and Regular Expressions.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace Propress
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
string text = richTextBox1.Text;
ICollection<string> matches =
Regex.Matches(text.Replace(Environment.NewLine, ""), #"\(([^)]*)\)")
.Cast<Match>()
.Select(x => x.Groups[1].Value)
.ToList();
foreach (string match in matches)
MessageBox.Show(match);
}
}
}

string textBox = richTextBox1.Text;
textBox = textBox.Replace("testname(", "");
// Now textBox has the string you are looking for

Related

Search list of filenames with wildcards

I have a list of filenames and one DOS-style wildcard as the search parameter.
List<string> filenames = FileNames;
How can I receive only files which match my wildcard ("p*.doc", "w*.*", "??r.doc?", and so on)?
Yes, I know about Directory.GetFiles, but I don't have a directory. Only filenames.
What you could do is make a regex from the DOS-style wildcard filename specification, then you can select the filenames from the list which match the regex, something like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static string DosWildcardToRegex(string dwc)
{
string s = "";
foreach (char c in dwc)
{
if (c == '.') { s += #"\."; }
else if (c == '*') { s += ".*?"; }
else if (c == '?') { s += "."; }
else s += Regex.Escape(c.ToString());
}
return "^" + s + "$";
}
static void Main(string[] args)
{
string userWildcardSpec = "p*.xls*";
string reWildcard = DosWildcardToRegex(userWildcardSpec);
Regex re = new Regex(reWildcard, RegexOptions.IgnoreCase);
var sampleFilenames = new List<string>() { "a1.xls", "p2.txt", "p1.xls", "p234.xls", "p7.xlsx" };
var matchedFilenames = sampleFilenames.Where(f => re.IsMatch(f));
Console.WriteLine(string.Join("\r\n", matchedFilenames));
Console.ReadLine();
}
}
}
Which outputs:
p1.xls
p234.xls
p7.xlsx
In a regex, a . is a special character which means "any character", so it needs to be escaped as \..
In a DOS wildcard, * means zero-or-more of any character, which is .*? in a regex (the ? makes it "non-greedy").
In a DOS wildcard, ? means one character, which is . in a regex.
In case there is some other special regex character, they are escaped where necessary.
The ^ and $ mean the start and end of the string respectively, so it won't get an unwanted match from the middle of a filename.
The easiest way:
using Microsoft.VisualBasic.CompilerServices;
...
var filenames = new List<string>() { "b.pdf", "al.rtf", "mel.doc"};
var matched = filenames.Where(f => LikeOperator.LikeString(f, "*.d*", CompareMethod.Text));

Split string into multiple alpha and numeric segments

I have a string like "ABCD232ERE44RR". How can I split it into separate segments by letters/numbers. I need:
Segment1: ABCD
Segment2: 232
Segment3: ERE
Segment4: 44
There could be any number of segments. I am thinking go Regex but don't understand how to write it properly
You can do it like this;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
var substrings = Regex.Split("ABCD232ERE44RR", #"[^A-Z0-9]+|(?<=[A-Z])(?=[0-9])|(?<=[0-9])(?=[A-Z])");
Console.WriteLine(string.Join(",",substrings));
}
}
Output : ABCD,232,ERE,44,RR
I suggest thinking of this as finding matches to a target pattern rather than splitting into the parts you want. Splitting gives significance to the delimiters whereas matching gives significance to the tokens.
You can use Regex.Matches:
Searches the specified input string for all occurrences of a specified regular expression.
var matches = Regex.Matches("ABCD232ERE44RR", "[A-Z]+|[0-9]+");
foreach (Match match in matches) {
Console.WriteLine("Found '{0}' at position {1}", match.Value, match.Index);
}
Try something like:
((A-Z)+(\d)*)+
If you decide not to use regex, you can always go the manual route.
const string str = "ABCD232ERE44RR1SGGSG3333GSDGSDG";
var result = new List<StringBuilder>
{
new StringBuilder()
};
char last = str[0];
result.Last().Append(last);
bool isLastNum = Char.IsNumber(last);
for (int i = 1; i < str.Length; i++)
{
char ch = str[i];
if (!((Char.IsDigit(ch) && isLastNum) || (Char.IsLetter(ch) && !isLastNum)))
{
result.Add(new StringBuilder());
}
result.Last().Append(ch);
last = ch;
isLastNum = Char.IsDigit(ch);
}

How do I replace specific characters from a c# string?

if I have a string along the lines of: "user:jim;id:23;group:49st;"
how can I replace the group code (49st) with something else, so that it shows: "user:jim;id=23;group:76pm;"
sorry if the question is easy but I haven't found a specific answer, just cases different than mine.
You can use the index of "group" like this
string s = "user:jim;id:23;group:49st;";
string newS = s.Substring(0,s.IndexOf("group:") + 6);
string restOfS = s.IndexOf(";",s.IndexOf("group:") + 6) + 1 == s.Length
? ""
: s.Substring(s.IndexOf(";",s.IndexOf("group:") + 6) + 1);
newS += "76pm;";
s = newS + restOfS;
The line with the s = criteria ? true : false is essentially an if but it is put onto one line using a ternary operator.
Alternatively, if you know what text is there already and what it should be replaced with, you can just use a Replace
s = s.Replace("49st","76pm");
As an added precaution, if you are not always going to have this "group:" part in the string, to avoid errors put this inside an if which checks first
if(s.Contains("group:"))
{
//Code
}
Find the match using regex and replace it with new value in original string as mentioned below:
string str = "user:jim;id=23;group:49st;";
var match = Regex.Match(str, "group:.*;").ToString();
var newGroup = "group:76pm;";
str = str.Replace(match, newGroup);
This solution should work no matter where the group appears in the string:
string input = "user:jim;id:23;group:49st;";
string newGroup = "76pm";
string output = Regex.Replace(input, "(group:)([^;]*)", "${1}"+newGroup);
Here is a very generic method for splitting your input, changing items, then rejoining items to a string. It is not meant for single replacement in your example, but is meant to show how to split and join items in string.
I used Regex to split the items and then put results into a dictionary.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string pattern = "(?'name'[^:]):(?'value'.*)";
string input = "user:jim;id:23;group:49st";
Dictionary<string,string> dict = input.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => new
{
name = Regex.Match(x, pattern).Groups["name"].Value,
value = Regex.Match(x, pattern).Groups["value"].Value
}).GroupBy(x => x.name, y => y.value)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
dict["group"] = "76pm";
string output = string.Join(";",dict.AsEnumerable().Select(x => string.Join(":", new string[] {x.Key, x.Value})).ToArray());
}
}
}
That is just one way to do it. I hope it will help you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace stringi
{
class Program
{
static void Main(string[] args)
{
//this is your original string
string s = "user:jim;id:23;group:49st";
//string with replace characters
string s2 = "76pm";
//convert string to char array so you can rewrite character
char[] c = s.ToCharArray(0, s.Length);
//asign characters to right place
c[21] = s2[0];
c[22] = s2[1];
c[23] = s2[2];
c[24] = s2[3];
//this is your new string
string new_s = new string(c);
//output your new string
Console.WriteLine(new_s);
Console.ReadLine();
}
}
}
string a = "user:jim;id:23;group:49st";
string b = a.Replace("49st", "76pm");
Console.Write(b);

Combine TrimStart and TrimEnd for a String

I have a string with some letters and numbers. here an exemple :
OG000134W4.11
I have to trim all the first letters and the first zeros to get this :
134W4.11
I also need to cut the character from the first letter he will encounter to finally retreive :
134
I know I can do this with more than one "trim" but I want to know if there was an efficient way to do that.
Thanks.
If you don't want to use regex.. then Linq is your friend
[Test]
public void TrimTest()
{
var str = "OG000134W4.11";
var ret = str.SkipWhile(x => char.IsLetter(x) || x == '0').TakeWhile(x => !char.IsLetter(x));
Assert.AreEqual("134", ret);
}
Here is the regex I would use
([1-9][0-9]*)[^1-9].*
Here is some C# code you could try
var input = "OG000134W4.11";
var result = new Regex(#"([1-9][0-9]*)[^1-9].*").Replace(input, "$1");
using System;
using System.Text.RegularExpressions;
namespace regex
{
class MainClass
{
public static void Main (string[] args)
{
string result = matchTest("OG000134W4.11");
Console.WriteLine(result);
}
public static string matchTest (string input)
{
Regex rx = new Regex(#"([1-9][0-9]+)\w*[0-9]*\.[0-9]*");
Match match = rx.Match(input);
if (match.Success){
return match.Groups[1].Value;
}else{
return string.Empty;
}
}
}
}

C# Split string into array based on prior character

I need to take a string and split it into an array based on the type of charcter not matching they proceeding it.
So if you have "asd fds 1.4#3" this would split into array as follows
stringArray[0] = "asd";
stringArray[1] = " ";
stringArray[2] = "fds";
stringArray[3] = " ";
stringArray[4] = "1";
stringArray[5] = ".";
stringArray[6] = "4";
stringArray[7] = "#";
stringArray[8] = "3";
Any recomendations on the best way to acheive this? Of course I could create a loop based on .ToCharArray() but was looking for a better way to achieve this.
Thank you
Using a combination of Regular Expressions and link you can do the following.
using System.Text.RegularExpressions;
using System.Linq;
var str="asd fds 1.4#3";
var regex=new Regex("([A-Za-z]+)|([0-9]+)|([.#]+)|(.+?)");
var result=regex.Matches(str).OfType<Match>().Select(x=>x.Value).ToArray();
Add additional capture groups to capture other differences. The last capture (.+?) is a non greedy everything else. So every item in this capture will be considered different (including the same item twice)
Update - new revision of regex
var regex=new Regex(#"(?:[A-Za-z]+)|(?:[0-9]+)|(?:[#.]+)|(?:(?:(.)\1*)+?)");
This now uses non capturing groups so that \1 can be used in the final capture. This means that the same character will be grouped if its in then catch all group.
e.g. before the string "asd fsd" would create 4 strings (each space would be considered different) now the result is 3 strings as 2 adjacent spaces are combined
Use regex:
var mc = Regex.Matches("asd fds 1.4#3", #"([a-zA-Z]+)|.");
var res = new string[mc.Count];
for (var i = 0; i < mc.Count; i++)
{
res[i] = mc[i].Value;
}
This program produces exactly output you want, but I am not sure wether it's generic enaugh for your goal.
class Program
{
private static void Main(string[] args)
{
var splited = Split("asd fds 1.4#3").ToArray();
}
public static IEnumerable<string> Split(string text)
{
StringBuilder result = new StringBuilder();
foreach (var ch in text)
{
if (char.IsLetter(ch))
{
result.Append(ch);
}
else
{
yield return result.ToString();
result.Clear();
yield return ch.ToString(CultureInfo.InvariantCulture);
}
}
}
}

Categories