I'm trying to get the function DoDialogwizardWithArguments that is inside a string using Regex:
string:
var a = 1 + 2;DoDialogWizardWithArguments('CopyGroup', '&act=enviarcliente', 96487, (Q.getBody().$.innerWidth()/4)*3, Q.getBody().$.innerHeight(), new Function("if(localStorage.getItem('atualizaPgsParaCli')){{Q.window.close();Q.window.proxy.reload();}}localStorage.removeItem('atualizaPgsParaCli');return true;"), false);p = q.getBOdy();
actual Regex (pattern):
DoDialogWizardWithArguments\((.*\$?)\)
Result expected:
DoDialogWizardWithArguments('CopyGroup', '&act=enviarcliente', 96487, (Q.getBody().$.innerWidth()/4)*3, Q.getBody().$.innerHeight(), new Function("if(localStorage.getItem('atualizaPgsParaCli')){{Q.window.close();Q.window.proxy.reload();}}localStorage.removeItem('atualizaPgsParaCli');return true;"), false)
The problem:
If there's another parentheses ")" that is not the parentheses of DoDialogWizardWithArguments function the Regex is getting this too.
How can i get only the function with his open and close parentheses.
If Regex is not possible, whats the better option?
Example regex link:https://regex101.com/r/kP2bQ4/1
Try this one as regex: https://regex101.com/r/kP2bQ4/2
DoDialogWizardWithArguments\(((?:[^()]|\((?1)\))*+)\)
I'd probably try to simplify it like this:
var str = #"var a = 1 + 2;DoDialogWizardWithArguments('CopyGroup', '&act=enviarcliente', 96487, (Q.getBody().$.innerWidth()/4)*3, Q.getBody().$.innerHeight(), new Function("if(localStorage.getItem('atualizaPgsParaCli')){{Q.window.close();Q.window.proxy.reload();}}localStorage.removeItem('atualizaPgsParaCli');return true;"), false);p = q.getBOdy();"
var lines = str.Split(';');
foreach(var line in lines)
{
if(line.Contains("DoDialogWizardWithArguments")){
int startPos = line.IndexOf("(");
int endPos = line.IndexOf(")");
return line.Substring(startPos+1, endPos - startPos - 1);
}
}
return "Not found";
If you don't want to detect if DoDialogWizardWithArguments was correctly written but just the function itself, try with "DoDialogWizardWithArguments([^,],[^,],[^,],([^,]),.+);".
Example:
String src = #"xdasadsdDoDialogWizardWithArguments('CopyGroup', '&act=enviarcliente', 96487, (Q.getBody().$.innerWidth()/4)*3, Q.getBody().$.innerHeight(), new Function(" + "\""
+ "if(localStorage.getItem('atualizaPgsParaCli')){{Q.window.close();Q.window.proxy.reload();}}localStorage.removeItem('atualizaPgsParaCli');return true;"
+ "\"" + "), false);p"; //An example of what you asked for
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(#"DoDialogWizardWithArguments([^,]*,[^,]*,[^,]*,([^,]*),.+);"); //This is your function
MessageBox.Show(r.Match(src).Value);
if (r.IsMatch(src))
MessageBox.Show("Yeah, it's DoDialog");
else MessageBox.Show("Nope, Nope, Nope");
Related
string url = "test:app:https://test#hotmail.co.uk:Test
I need to split this up to display as follows
string first = "app";
string second = "https://test#hotmail.co.uk:Test";
i have tried the following but falls over on the last colon.
string remove= "";
remove= url.Replace("test:", "");
string first= remove.Substring(remove.LastIndexOf(':') + 1);
string second= remove.Substring(0, remove.IndexOf(':'));
Doing this i get
first = "app";
second = "Test";
When i need
first = "app";
second = "https://test#hotmail.co.uk:Test";
Your use of LastIndexOf is just a bit wonky.
string url = "test:app:https://test#hotmail.co.uk:Test";
string remove = url.Replace("test:", "");
string first = remove.Substring(0, remove.IndexOf(":"));
string second = remove.Substring(remove.IndexOf(first) + first.Length + 1);
First grab the app, and we can use the location of app to derive the rest of the string. Because the last index of : would be the one in :Test. We don't want the last index of :. Instead we just want whatever comes after app.
As everything is prefixed with test: you can use a starting position after that and then split after the first occurrance of the : character.
const int IndexOfPrefix = 5; // start position after "test:"
string url = "test:app:https://test#hotmail.co.uk:Test";
var indexOfApp = url.IndexOf(':', IndexOfPrefix);
var part1 = url.Substring(IndexOfPrefix, indexOfApp - IndexOfPrefix);
var part2 = url.Substring(indexOfApp + 1);
Console.WriteLine(part1);
Console.WriteLine(part2);
Something like this should do the trick:
public void ManipulateStrings()
{
string url = "test:app:https://test#hotmail.co.uk:Test";
url = url.Replace("test:", "");
string first = url.Substring(0, url.IndexOf(':'));
string second = url.Substring(url.IndexOf(':') + 1);
}
This basically removed test: from your string, then assigns first and second their values without creating string remove = "" for no reason.
You can use Split(Char[], Int32) to get the desired number of elements (3 : the first unwanted part, the first expected part and the remaining) along with Skip() to remove the unwanted one :
string url = "test:app:https://test#hotmail.co.uk:Test";
var splitted = url.Split(new [] { ':' }, 3).Skip(1).ToArray();
var first = splitted[0];
var second = splitted[1];
Console.WriteLine(first);
Console.WriteLine(second);
This outputs
app
https://test#hotmail.co.uk:Test
Another way to do that is using regular expressions :
The pattern :(?<first>.*?):(?<second>.*) will :
: search for the characters :
(?<first>.*?) creates a group named first that will match any number of any character (lazy)
: search for the characters :
(?<second>.*) creates a group named second that will match any number of any character (greedy)
In example :
string url = "test:app:https://test#hotmail.co.uk:Test";
var pattern = ":(?<first>.*?):(?<second>.*)";
var regex = new Regex(pattern); // using System.Text.RegularExpressions;
Match match = regex.Match(url);
if (match.Success)
{
var first = match.Groups["first"].Value;
var second = match.Groups["second"].Value;
Console.WriteLine(first);
Console.WriteLine(second);
}
This outputs
app
https://test#hotmail.co.uk:Test
you need to change the variable with name "first" to "second" and to change the variable with name "second" to "first"
This is your code:
string url = "test:app:https://test#hotmail.co.uk:Test";
string remove = "";
remove = url.Replace("test:", "");
string second = remove.Substring(0, remove.IndexOf(':'));
string first = remove.Substring(remove.IndexOf(":") + 1);
and this is the correct code:
string url = "test:app:https://test#hotmail.co.uk:Test";
string remove = "";
remove = url.Replace("test:", "");
string first = remove.Substring(0, remove.IndexOf(':'));
string second = remove.Substring(remove.IndexOf(":") + 1);
I have string:
string mystring = "hello(hi,mo,wo,ka)";
And i need to get all arguments in brackets.
Like:
hi*mo*wo*ka
I tried that:
string res = "";
string mystring = "hello(hi,mo,wo,ka)";
mystring.Replace("hello", "");
string[] tokens = mystring.Split(',');
string[] tokenz = mystring.Split(')');
foreach (string s in tokens)
{
res += "*" + " " + s +" ";
}
foreach (string z in tokenz)
{
res += "*" + " " + z + " ";
}
return res;
But that returns all words before ",".
(I need to return between
"(" and ","
"," and ","
"," and ")"
)
You can try to use \\(([^)]+)\\) regex get the word contain in brackets,then use Replace function to let , to *
string res = "hello(hi,mo,wo,ka)";
var regex = Regex.Match(res, "\\(([^)]+)\\)");
var result = regex.Groups[1].Value.Replace(',','*');
c# online
Result
hi*mo*wo*ka
This way :
Regex rgx = new Regex(#"\((.*)\)");
var result = rgx.Match("hello(hi,mo,wo,ka)");
Split method has an override that lets you define multiple delimiter chars:
string mystring = "hello(hi,mo,wo,ka)";
var tokens = mystring.Replace("hello", "").Split(new[] { "(",",",")" }, StringSplitOptions.RemoveEmptyEntries);
So I have a long string containing pointy brackets that I wish to extract text parts from.
string exampleString = "<1>text1</1><27>text27</27><3>text3</3>";
I want to be able to get this
1 = "text1"
27 = "text27"
3 = "text3"
How would I obtain this easily? I haven't been able to come up with a non-hacky way to do it.
Thanks.
Using basic XmlReader and some other tricks to do wrapper to create XML-like data, I would do something like this
string xmlString = "<1>text1</1><27>text27</27><3>text3</3>";
xmlString = "<Root>" + xmlString.Replace("<", "<o").Replace("<o/", "</o") + "</Root>";
string key = "";
List<KeyValuePair<string,string>> kvpList = new List<KeyValuePair<string,string>>(); //assuming the result is in the KVP format
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString))){
bool firstElement = true;
while (xmlReader.Read()) {
if (firstElement) { //throwing away root
firstElement = false;
continue;
}
if (xmlReader.NodeType == XmlNodeType.Element) {
key = xmlReader.Name.Substring(1); //cut of "o"
} else if (xmlReader.NodeType == XmlNodeType.Text) {
kvpList.Add(new KeyValuePair<string,string>(key, xmlReader.Value));
}
}
}
Edit:
The main trick is this line:
xmlString = "<Root>" + xmlString.Replace("<", "<o").Replace("<o/", "</o") + "</Root>"; //wrap to make this having single root, o is put to force the tagName started with known letter (comment edit suggested by Mr. chwarr)
Where you first replace all opening pointy brackets with itself + char, i.e.
<1>text1</1> -> <o1>text1<o/1> //first replacement, fix the number issue
and then reverse the sequence of all the opening point brackets + char + forward slash to opening point brackets + forward slash + char
<o1>text1<o/1> -> <o1>text1</o1> //second replacement, fix the ending tag issue
Using simple WinForm with RichTextBox to print out the result,
for (int i = 0; i < kvpList.Count; ++i) {
richTextBox1.AppendText(kvpList[i].Key + " = " + kvpList[i].Value + "\n");
}
Here is the result I get:
This is far from bulletproof, but you could use a combination of split and Regex matching:
string exampleString = "<1>text1</1><27>text27</27><3>text3</3>";
string[] results = exampleString.Split(new string[] { "><" }, StringSplitOptions.None);
Regex r = new Regex(#"^<?(\d+)>([^<]+)<");
foreach (string result in results)
{
Match m = r.Match(result);
if (m.Success)
{
string index = m.Groups[1].Value;
string value = m.Groups[2].Value;
}
}
The most non-bulletproof example I can think of is if your text contains a "<", that would pretty much break this.
I have taken my regex from python and try to make work in c#, while i get no errors, it does not display any output and during debug, i do not see the output varible get populated with any data, here is snippet:
StringWriter strwriter = new StringWriter();
rule = sr.ReadLine();
do
{
Regex action = new Regex(#"^#\w+(?<action>(alert)\\s+(tcp|udp)\\s+(.*?)\\('*}))");
Regex message = new Regex("(?<msg>[\\s(]*\\((.*)\\)[^)]*$)", RegexOptions.IgnorePatternWhitespace);
Regex content = new Regex("(?<content>[\\s(]*\\((.*)\\)[^)]*$)", RegexOptions.IgnorePatternWhitespace);
Match result = action.Match(rule);
//String repl = Regex.Replace(rule, "[\\;]", ",");
//Match mat = action.Match(repl);
Console.WriteLine(result.Groups["action"].Value);
//writer.WriteLine(result.Groups["action"].Value + "," + result.Groups["msg"].Value + "," + result.Groups["content"].Value + "," + result.Groups["flow"].Value + "," + result.Groups["ct"].Value + "," + result.Groups["pcre"].Value + "," + result.Groups["sid"].Value);
} while (rule != null);
result does not show anything, what have i missed, these are almost the same one that i have working in the python script.
Since you're using string literals for the first regex, don't double escape!
^#\w+(?<action>(alert)\\s+(tcp|udp)\\s+(.*?)\\('*}))
^ ^ ^
=>
^#\w+(?<action>(alert)\s+(tcp|udp)\s+(.*?)\('*}))
With the input, there were a couple of more things wrong with the regex and this one should bring you in the right direction:
^#\s*(?<action>alert\s+(?:tcp|udp)\s+(.*?)\([^)]*\))
regex101 demo
If you don't want the part within parentheses, you can omit the last part:
^#\s*(?<action>alert\s+(?:tcp|udp)\s+(.*?)\()
I am fairly new to c# and am working on a little project but got stuck on this. I have a file that contains some assembly code. I want my program to search this file for a string, actually a value right after my string. One of the strings i am searching for is:
setproperty QName(PackageNamespace(""), "font")
getlocal 4
pushint
My search code is this:
private void searchFile(String searchText)
{
System.IO.StreamReader reader = new System.IO.StreamReader(file);
String text = reader.ReadToEnd();
if (Regex.IsMatch(text, searchText))
{
MessageBox.Show(searchText + " was found in the given file", "Finally!!");
}
else
{
MessageBox.Show("Sorry, but " + searchText + " could not be found in the given file", "No Results");
}
}
//when i click a button//
searchFile(#"setproperty QName(PackageNamespace(""""), ""font"")
getlocal 4
pushint ");
I know that the string is in the file but the result comes up with not found. I don't know if it is the quotes or tabs or both that is causing this.
Here is part of the file:
getlocal 4
pushstring "Verdana"
setproperty QName(PackageNamespace(""), "font")
getlocal 4
pushint 16764170
setproperty QName(PackageNamespace(""), "color")
getlocal 4
pushbyte 12
setproperty QName(PackageNamespace(""), "size")
My second question is how can i get the value of the first int after my search result?
Thanks in advance.
-Leen
You should change your method like this:
private static string searchFile(String searchText)
{
System.IO.StreamReader reader = new System.IO.StreamReader("test.txt");
String text = reader.ReadToEnd();
int poz = text.IndexOf(searchText);
if (poz >= 0)
{
int start = poz + searchText.Length;
int end = text.IndexOf("\n", start);
Console.WriteLine(searchText + " was found in the given file", "Finally!!");
return text.Substring(start, end - start);
}
else
{
Console.WriteLine("Sorry, but " + searchText + " could not be found in the given file", "No Results");
return string.Empty;
}
}
The call:
string val = searchFile("setproperty QName(PackageNamespace(\"\"), \"font\")\r\n\r\n getlocal 4\r\n pushint ");
So I think you may be use to VB.net. C-based languages (like c#) used the backslash character "\" as an escape character.
So in a searching for a double-quote in a string you would need to escape it using \".
I believe what you're looking for is:
searchFile(#"setproperty QName(PackageNamespace(\"\"), \"font\")
getlocal 4
pushint ");
But this isn't really a regular expression, which is what the Regex class is meant for. So I would (well not really, I would clean it up a bit, like not mix my UI and bizlogic) do this:
// Added String as the function type so you can return the matched "Integer" as a string, you could always do a Int32.TryParse(...)
private String searchFile(String file, String searchText)
{
System.IO.StreamReader reader = new System.IO.StreamReader(file);
String text = reader.ReadToEnd();
int32 index = text.IndexOf(searchText);
if (index >= 0) //We could find it at the very beginning
{
MessageBox.Show(searchText + " was found in the given file", "Finally!!");
int32 start = index + searchText.Length;
int32 end = Regex.Match(text, "[\n\r\t]", index).Index; // This will search for whitespace
String value = text.Substring(start, end - start);
// Now you can do something with your value, like...
return value;
}
else
{
MessageBox.Show("Sorry, but " + searchText + " could not be found in the given file", "No Results");
return "";
}
}