I have a code in String and I need to select only the method that I want, for example:
"public void GetEntities(List<PublisherBO> _publishers, WebResourceBO _webResourceBO, SqlBO _sqlBO) {
List<EntityBO> entities = new List<EntityBO>();
List<EntityMetadata> results = entityDAO.GetAllEntities();
EntitiesMetadata = results;
entities = ConvertEntities(results);
Data = entities;
}
public void ResetConnection() {
sqlOpen = false;
dynamicsOpen = false;
if (Service != null) {
if (Service.OrganizationWebProxyClient != null)
Service.OrganizationWebProxyClient.Close();
Service.Dispose();
}
}"
And I want to select only this:
"public void ResetConnection() {
sqlOpen = false;
dynamicsOpen = false;
if (Service != null) {
if (Service.OrganizationWebProxyClient != null)
Service.OrganizationWebProxyClient.Close();
Service.Dispose();
}
}"
I know that I have to use IndexOf Methods, the complicated is consider the { } because I know that I need to finish the select on code in } but how to consider the others { } inside this block of code and precisely select all method.
And a note: I cannot divide this in lines, because some codes have only 1 line (javascript)
This is a regex pattern that will work to match code blocks. It can fail if there are unclosed {} inside of strings.
(.*?){(?:[^{}]+|{(?<n>)|}(?<-n>))+(?(n)(?!))*}
Regex Storm
Here is a working example in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main (string[] args)
{
var text = #"public void GetEntities(List<PublisherBO> _publishers, WebResourceBO _webResourceBO, SqlBO _sqlBO) {
List<EntityBO> entities = new List<EntityBO>();
List<EntityMetadata> results = entityDAO.GetAllEntities();
EntitiesMetadata = results;
entities = ConvertEntities(results);
Data = entities;
}
public void ResetConnection() {
sqlOpen = false;
dynamicsOpen = false;
if (Service != null) {
if (Service.OrganizationWebProxyClient != null)
Service.OrganizationWebProxyClient.Close();
Service.Dispose();
}
}";
var matches = Regex.Matches(text, "(.*?){(?:[^{}]+|{(?<n>)|}(?<-n>))+(?(n)(?!))*}");
if (matches.Count > 0)
{
}
}
}
}
Here is a link to regex storm showing the original pattern matching C# code as well as JS code with various syntax
Regex Storm with C# and JS
Related
i am using a method to retrieve data from an OPC DA server using TitaniumAS packages, the problem i am having is that i have a lot of tags to read/write so i have to use methods.
The WriteX method works fines as it doesnt have to return anything but the read does not, well it does its job, it reads but i cannot use that data outside of the method because it was a void method, when i tried to use it as a String method (that's the type of data i need) it says :
Error CS0161 'ReadX(string, string)': not all code paths return a value
PS : note that i am just a beginner in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TitaniumAS.Opc.Client.Common;
using TitaniumAS.Opc.Client.Da;
using TitaniumAS.Opc.Client.Da.Browsing;
using System.Threading;
using System.Threading.Channels;
using Async;
namespace OPCDA
{
class Program
{
static void Main(string[] args)
{
TitaniumAS.Opc.Client.Bootstrap.Initialize();
Uri url = UrlBuilder.Build("Kepware.KEPServerEX.V6");
using (var server = new OpcDaServer(url))
{
server.Connect();
OpcDaGroup group = server.AddGroup("MyGroup");
group.IsActive = true;
Ascon ascon1 = new Ascon();
ReadX("Channel1.Ascon1.AsconS", ascon1.ALM);
Console.WriteLine("value = {0}", ascon1.ALM);
void WriteX(String Link, String Ascon)
{
var definition1 = new OpcDaItemDefinition
{
ItemId = Link,
IsActive = true
};
OpcDaItemDefinition[] definitions = { definition1 };
OpcDaItemResult[] results = group.AddItems(definitions);
OpcDaItem tag = group.Items.FirstOrDefault(i => i.ItemId == Link);
OpcDaItem[] items = { tag };
object[] Values = { Ascon };
HRESULT[] Results = group.Write(items, Values);
}
string ReadX(String Link, String read)
{
var definition1 = new OpcDaItemDefinition
{
ItemId = Link,
IsActive = true
};
OpcDaItemDefinition[] definitions = { definition1 };
OpcDaItemResult[] results = group.AddItems(definitions);
OpcDaItemValue[] values = group.Read(group.Items, OpcDaDataSource.Device);
read = Convert.ToString(values[0].Value);
}
}
}
}
}
the first step was to state the return like this :
return Convert.ToString(values[0].Value) instead of read = Convert.ToString(values[0].Value)
then go up and use that value with my variable :
ascon1.ALM=ReadX("Channel1.Ascon1.AsconS");
I've been trying to parse and search for a specific word in a big string, but I can't seem to be able to figure it out. I have created a script that connects a Twitch Channel's chat into unity.
An example of a message would be:
"#badge-info=subscriber/4;badges=moderator/1,subscriber/3,bits/1;bits=1;color=;display-name=TwitchUser1234;emotes=;flags=;id=da6ec4c6-af61-4346-abc-123456789;mod=1;room-id=12345678;subscriber=1;tmi-sent-ts=160987654321;turbo=0;user-id=123456789;user-type=mod :TwitchUser1234#TwitchUser1234.tmi.twitch.tv PRIVMSG #thechannelyouarewatching :PogChamp1 Another Test Bit"
I tried parsing and searching for the string 'bits' the message by doing:
private void GameInputs(string ChatInputs)
{
string Search;
Search = ChatInputs.Split(";", "=");
if(string "bits" in Search)
{
print("I made it here.");
}
}
I'm at a complete loss and have no idea how to do this. Any help is appreciated.
If my full code is needed it is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.ComponentModel;
using System.Net.Sockets;
using System.IO;
public class TwitchChat : MonoBehaviour
{
private TcpClient twitchClient;
private StreamReader reader;
private StreamWriter writer;
public string username, password, channelName; // http://twitchapps.com/tmi
// Start is called before the first frame update
void Start()
{
Connect();
}
void Update()
{
if(!twitchClient.Connected)
{
Connect();
}
ReadChat();
}
private void Connect()
{
twitchClient = new TcpClient("irc.chat.twitch.tv", 6667);
reader = new StreamReader(twitchClient.GetStream());
writer = new StreamWriter(twitchClient.GetStream());
writer.WriteLine("PASS " + password);
writer.WriteLine("NICK " + username);
writer.WriteLine("USER " + username + " 8 * :" + username);
writer.WriteLine("JOIN #" + channelName);
writer.WriteLine("CAP REQ :twitch.tv/tags");
writer.Flush();
}
private void ReadChat()
{
if (twitchClient.Available > 0)
{
var message = reader.ReadLine();
print(message);
GameInputs(message);
}
}
private void GameInputs(string ChatInputs)
{
string Search;
Search = ChatInputs.Split(";", "=");
if(string "bits" in Search)
{
print("I made it here.");
}
}
}
If you want to pull the value of "bits=xx" out, this would do it:
var b = value.Split(';').FirstOrDefault(s => s.StartsWith("bits="))?[5..];
b will be null if "bits=" is not present
If you're going to parse a lot of values out of this string consider turning it into a dictionary:
var c = new []{'='};
var d = value.Split(';').ToDictionary(s => s.Split(c,2)[0], s => s.Split(c,2)[1]);
It's slightly inefficient to split twice, if it bothers you, you can sub string:
value.Split(';').ToDictionary(s => s[..s.IndexOf('=')], s => s[s.IndexOf('=')+1..]);
This gives a dictionary of string, so you can do like:
if(d.ContainsKey("bits")){
var bits = int.Parse(d["bits"]);
...
String has a method Contains(string) that does the job:
if (ChantInputs.Contains("bits")
{
print("I made it here.");
}
You can try below.
private void GameInputs(string ChatInputs)
{
string[] Search = ChatInputs.Split(new char[] { ';', '=' });
foreach(string s in Search)
{
if(s == "bits")
{
print("I made it here.");
}
}
}
Below is the working code.
using System;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string str = "one;two;test;three;test+test";
string[] strs = str.Split(new char[] { ';', '+' });
foreach(string s in strs)
{
if(s == "test")
{
Console.WriteLine(s);
}
}
Console.ReadLine();
}
}
}
If we had some string like :
----------DBVer=1
/*some sql script*/
----------DBVer=1
----------DBVer=2
/*some sql script*/
----------DBVer=2
----------DBVer=n
/*some sql script*/
----------DBVer=n
Can we extract scripts between first DBVer=1 and second DBVer=1 and so on... with regex?
I thing we must have some placehoder for regex, and tel regex engine if saw DBVer=digitA pick string until DBVer=digitA again if saw DBVer=digitB pick string until DBVer=digitB and so on...
Can we implement this with regex and if we can how?
Yes, using backreferences and lookarounds, you can capture the scripts:
var pattern = #"(?<=(?<m>-{10}DBVer=\d+)\r?\n).*(?=\r?\n\k<m>)";
var scripts = Regex.Matches(input, pattern, RegexOptions.Singleline)
.Cast<Match>()
.Select(m => m.Value);
Here, we capture the m (marker) group with (?<m>-{10}DBVer=\d+) and reuse the m value later in the regex with \k<m> to match against the end marker.
In order for .* to match newline chars, it is necessary to turn on Singleline mode. This, in turn, means we have to be specific about our newlines. In Singleline mode, these can be accounted for in a non-platform specific way with \r?\n.
Try code below. Not RegEx but works very well.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace ConsoleApplication6
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
Script.ReadScripts(FILENAME);
}
}
public class Script
{
enum State
{
Get_Script,
Read_Script
}
public static List<Script> scripts = new List<Script>();
public int version { get; set; }
public string script { get; set; }
public static void ReadScripts(string filename)
{
string inputLine = "";
string pattern = "DBVer=(?'version'\\d+)";
State state = State.Get_Script;
StreamReader reader = new StreamReader(filename);
Script newScript = null;
while ((inputLine = reader.ReadLine()) != null)
{
inputLine = inputLine.Trim();
if (inputLine.Length > 0)
{
switch (state)
{
case State.Get_Script :
if(inputLine.StartsWith("-----"))
{
newScript = new Script();
scripts.Add(newScript);
string version =
Regex.Match(inputLine, pattern).Groups["version"].Value;
newScript.version = int.Parse(version);
newScript.script = "";
state = State.Read_Script;
}
break;
case State.Read_Script :
if (inputLine.StartsWith("-----"))
{
state = State.Get_Script;
}
else
{
if (newScript.script.Length == 0)
{
newScript.script = inputLine;
}
else
{
newScript.script += "\n" + inputLine;
}
}
break;
}
}
}
}
}
}
Hi please can anyone give me solution to this problem,i have to import csv file using c# but i have this problem in this screenshot
Screen
the separate betwenn column is ',' but in the data there is a rows tha contains ".
Mohamed, I cannot see your screenshot, but can point you toward generic lists and creating a class to represent data. You will need to add references from the "Project" menu.
Microsoft.VisualBasic
System.Configuration
WindowsBase
I am including code from a snippet of code where I was doing that:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualBasic.FileIO;
namespace CsvToListExp
{
class Program
{
public static void Main(string[] args)
{
// HARD_CODED FOR EXAMPLE ONLY - TO BE RETRIEVED FROM APP.CONFIG IN REAL PROGRAM
string hospPath = #"C:\\events\\inbound\\OBLEN_COB_Active_Inv_Advi_Daily_.csv";
string vendPath = #"C:\\events\\outbound\\Advi_OBlen_Active_Inv_Ack_Daily_.csv";
List<DenialRecord> hospList = new List<DenialRecord>();
List<DenialRecord> vendList = new List<DenialRecord>();
//List<DenialRecord> hospExcpt = new List<DenialRecord>(); // Created at point of use for now
//List<DenialRecord> vendExcpt = new List<DenialRecord>(); // Created at point of use for now
using (TextFieldParser hospParser = new Microsoft.VisualBasic.FileIO.TextFieldParser(hospPath))
{
hospParser.TextFieldType = FieldType.Delimited;
hospParser.SetDelimiters(",");
hospParser.HasFieldsEnclosedInQuotes = false;
hospParser.TrimWhiteSpace = true;
while (!hospParser.EndOfData)
{
try
{
string[] row = hospParser.ReadFields();
if (row.Length <= 7)
{
DenialRecord dr = new DenialRecord(row[0], row[1], row[2], row[3], row[4], row[5], row[6]);
hospList.Add(dr);
}
}
catch (Exception e)
{
// do something
Console.WriteLine("Error is: {0}", e.ToString());
}
}
hospParser.Close();
hospParser.Dispose();
}
using (TextFieldParser vendParser = new Microsoft.VisualBasic.FileIO.TextFieldParser(vendPath))
{
vendParser.TextFieldType = FieldType.Delimited;
vendParser.SetDelimiters(",");
vendParser.HasFieldsEnclosedInQuotes = false;
vendParser.TrimWhiteSpace = true;
while (!vendParser.EndOfData)
{
try
{
string[] row = vendParser.ReadFields();
if (row.Length <= 7)
{
DenialRecord dr = new DenialRecord(row[0], row[1], row[2], row[3], row[4], row[5], row[6]);
vendList.Add(dr);
}
}
catch (Exception e)
{
// do something
Console.WriteLine("Error is: {0}", e.ToString());
}
}
vendParser.Close();
vendParser.Dispose();
}
// Compare the lists each way for denials not in the other source
List<DenialRecord> hospExcpt = hospList.Except(vendList).ToList();
List<DenialRecord> vendExcpt = vendList.Except(hospList).ToList();
}
}
}
Google TestFieldParser and look at the methods, properties and constructors. It is very versatile, but runs slowly due to the layers it goes through. It has the ability to set the delimiter, handle fields wrapped in quotes, trim whitespace and many more.
Just curious if there is a more simplified version to check if the given body has the word style of "Heading3" applied given this sample C# code I wrote learning the OpenXML library. To be clear, I am just asking given a body element how can I determine if the given body element has what word style applied. I eventually have to write a program that process numerous .DOCX files and need to process them from a top to bottom approach.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;
namespace docxparsing
{
class Program
{
static void Main()
{
string file_to_parse = #"C:\temp\sample.docx";
WordprocessingDocument doc = WordprocessingDocument.Open(file_to_parse,false);
Body body = doc.MainDocumentPart.Document.Body;
string fooStr
foreach( var foo in body )
{
fooStr = foo.InnerXml;
/*
these 2 comments represent 2 different xml snippets from 'fooStr'. the only way i figure out how to get the word style is by reading
this xml and doing checks for values. i don't know of any other approach in using the body element to check for the applied word style
<w:pPr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:pStyle w:val="Heading2" />
<w:pPr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:pStyle w:val="Heading3" />
*/
bool hasHeading3 = fooStr.Contains("pStyle w:val=\"Heading3\"");
if ( hasHeading3 )
{
Console.WriteLine("heading3 found");
}
}
doc.Close();
}
}
}
// -------------------------------------------------------------------------------
EDIT
Here is updated code of one way to do this. Still not overall happy with it but it works. Function to look at is getWordStyleValue(string x)
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace docxparsing
{
class Program
{
// ************************************************
// grab the word style value
// ************************************************
static string getWordStyleValue(string x)
{
int p = 0;
p = x.IndexOf("w:pStyle w:val=");
if ( p == -1 )
{
return "";
}
p = p + 15;
StringBuilder sb = new StringBuilder();
while (true)
{
p++;
char c = x[p];
if (c != '"')
{
sb.Append(c);
}
else
{
break;
}
}
string s = sb.ToString();
return s;
}
// ************************************************
// Main
// ************************************************
static void Main(string[] args)
{
string theFile = #"C:\temp\sample.docx";
WordprocessingDocument doc = WordprocessingDocument.Open(theFile,false);
string body_table = "DocumentFormat.OpenXml.Wordprocessing.Table";
string body_paragraph = "DocumentFormat.OpenXml.Wordprocessing.Paragraph";
Body body = doc.MainDocumentPart.Document.Body;
StreamWriter sw1 = new StreamWriter("paragraphs.log");
foreach (var b in body)
{
string body_type = b.ToString();
if (body_type == body_paragraph)
{
string str = getWordStyleValue(b.InnerXml);
if (str == "" || str == "HeadingNon-TOC" || str == "TOC1" || str == "TOC2" || str == "TableofFigures" || str == "AcronymList" )
{
continue;
}
sw1.WriteLine(str + "," + b.InnerText);
}
if ( body_type == body_table )
{
// sw1.WriteLine("Table:\n{0}",b.InnerText);
}
}
doc.Close();
sw1.Close();
}
}
}
Yes. You could do something like this:
bool ContainsHeading3 = body.Descendants<ParagraphSytleId>().Any(psId => psId.Val == "Heading3");
This will look at all the ParagraphStyleId elements (w:pStyle in the xml) and see if any of them have the Val of Heading3.
Just pasting this Edit from original post so he has better visibility.
Here is one solution I came up with. Yes, it a little cody ( if that is a word ) but working LINQ ( my fav ) to optimize a more elegant solution.
--
Here is updated code of one way to do this. Still not overall happy with it but it works. Function to look at is getWordStyleValue(string x)
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace docxparsing
{
class Program
{
// ************************************************
// grab the word style value
// ************************************************
static string getWordStyleValue(string x)
{
int p = 0;
p = x.IndexOf("w:pStyle w:val=");
if ( p == -1 )
{
return "";
}
p = p + 15;
StringBuilder sb = new StringBuilder();
while (true)
{
p++;
char c = x[p];
if (c != '"')
{
sb.Append(c);
}
else
{
break;
}
}
string s = sb.ToString();
return s;
}
// ************************************************
// Main
// ************************************************
static void Main(string[] args)
{
string theFile = #"C:\temp\sample.docx";
WordprocessingDocument doc = WordprocessingDocument.Open(theFile,false);
string body_table = "DocumentFormat.OpenXml.Wordprocessing.Table";
string body_paragraph = "DocumentFormat.OpenXml.Wordprocessing.Paragraph";
Body body = doc.MainDocumentPart.Document.Body;
StreamWriter sw1 = new StreamWriter("paragraphs.log");
foreach (var b in body)
{
string body_type = b.ToString();
if (body_type == body_paragraph)
{
string str = getWordStyleValue(b.InnerXml);
if (str == "" || str == "HeadingNon-TOC" || str == "TOC1" || str == "TOC2" || str == "TableofFigures" || str == "AcronymList" )
{
continue;
}
sw1.WriteLine(str + "," + b.InnerText);
}
if ( body_type == body_table )
{
// sw1.WriteLine("Table:\n{0}",b.InnerText);
}
}
doc.Close();
sw1.Close();
}
}
}