First off, I am not a c# person, so please bear with me on this one.
I need to replace the occurrences of "D:" with "d$" on a script task within SSIS. I sure use the replace function to do this, but the problem is, that this is having unintended consequences on another line.
For example, the script task sends out an email and the header of the email reads as \servername\d$ \further_path. The body of the email reads "UID: 1 : MESSAGE"
The line of code that sends the email reads like:
myHtmlMessage = new MailMessage(Dts.Variables["MailFromAddress"].Value.ToString(), Dts.Variables["MailRecipients"].Value.ToString(), Dts.Variables["MailSubjectSuccess"].Value.ToString(), Dts.Variables["MailBodySuccess"].Value.ToString().Replace("D:", #"\d$ "));
The current output that I get is:
Server Start Time: 3/21/2017 7:25:33 AM
Server End Time: 3/21/2017 7:27:39 AM
Total Run Time: 00:02:06.9402516
Log Folder: \\ServerNamed$\Apps\SSIS\Logs\
UId$ 2 -
The intended output is:
Server Start Time: 3/21/2017 7:25:33 AM
Server End Time: 3/21/2017 7:27:39 AM
Total Run Time: 00:02:06.9402516
Log Folder: \\ServerNamed$\Apps\SSIS\Logs\
UID: 2 -
Look at the log folder line and the UID line
When I use the replace function, the body line gets affected as well with the d$ symbol and that is what I am trying to avoid. Can I write a conditional REPLACE function in C# or, is there any other way to deal with this?
Thanks,
RV.
Have you looked into regular expressions?
https://msdn.microsoft.com/en-us/library/xwewhkd1(v=vs.110).aspx
Here's an example of how you would use it... note that I haven't tested this to determine if it fully functions, but it should help you get started down this path:
E.G.
// Assign your strings into variables to make your code cleaner:
string fromAddress = Dts.Variables["MailFromAddress"].Value.ToString();
string recipients = Dts.Variables["MailRecipients"].Value.ToString();
string subject = Dts.Variables["MailSubjectSuccess"].Value.ToString();
string body = Dts.Variables["MailBodySuccess"].Value.ToString();
// Replace D: in body
string pattern = "(Log Folder.+)D:"; // Capture the D: only if it's on the Log Folder line.
string replacement = "$1\\d$ "; // What we're replacing with.
Regex rgx = new Regex(pattern);
body = rgx.Replace(body, replacement);
// Build my HTML message.
myHtmlMessage = new MailMessage(fromAddress, recipients, subject, body);
I hope this helps...
Note - you can learn much more about regular expression syntax at http://www.regular-expressions.info/ . It's worth looking into if you want to learn how these engines work, how they might differ, and the best syntax to use for finding specific expressions under certain context.
Something along these lines will probably get you there:
string x = "Server Start Time: 3/21/2017 7:25:33 AM" +
"Server End Time: 3 / 21 / 2017 7:27:39 AM" +
"Total Run Time: 00:02:06.9402516" +
#"Log Folder: \\ServerNameD:\Apps\SSIS\Logs\" + Environment.NewLine +
"UID: 2 - ";
int lastNewlinw = x.LastIndexOf(Environment.NewLine);
string beginning = x.Substring(0, lastNewlinw).Replace("D:", #"\d$");
string result = string.Concat(beginning, x.Substring(lastNewlinw + 1, x.Length - beginning.Length));
Related
SOLVED! Ended up using this to do what I wanted:
if (output.Contains("<%TABLE#"))
{
string pattern = #"<%TABLE#([0-9]+)%%>";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(output, pattern, options))
{
int objectID = Int32.Parse(Regex.Match(m.Value, #"\d+").Value);
output = output.Replace(m.Value, ConvertFunction(objectID));
}
}
In some parts of my SQL data (rendered by a C#/ASP.NET website front-end) are strings, many of which can contain a pattern like <%TABLE#[NUMBER]%%> - [NUMBER] is always a specific ID, 1+. An example in one string would look like <%TABLE#3%%>. Sometimes there may be more than one of these patterns in the same string. I am ultimately trying to do the following:
Find all instances in the string where the pattern occurs
For each instance, call another building function using the # that is present - it takes that # and produces a NewString
Replace that instance of the code with NewString
I do this because each of the SQL tables has a website page to show the data within to the end-user. The way I format the data differs from table to table, so I have a Class for each table that builds the output string and returns it where needed. Sometimes, I need to display an object from a different table within the current one. To try and solve this, I added the above formula within the string, in the specific spot I want the object to be rendered, in the hopes of identifying it and using the ID within to grab the appropriate object, build it, then replace that pattern.
I'm guessing I'll have to use Regex or something to identify the string, but I'm struggling on the best way to grab the pattern, identify the number within, call the function to render the output text using said number, and then replace that specific pattern with the results.
Below are some example inputs and what the output should be. The function ConvertFormula takes in an INT and outputs a STRING.
EXAMPLE INPUTS/EXPECTED OUTPUT
Example 1:
"Here's some data and more stuff.<%TABLE#3541%%>Here is more text.
<%TABLE#31214%%>And some more."
Output 1:
"Here's some data and more stuff." + ConvertFormula(3541) + "Here is more text." + ConvertFormula(31214) + "And some more."
Example 2:
"Here's some data and more stuff! Maybe more here!<%TABLE#2%%>Here is more text."
Output 2:
"Here's some data and more stuff! Maybe more here!" + ConvertFormula(2) + "Here is more text."
Example 3:
"<%TABLE#2%%>This is something completely different with the object call at the start.<TABLE#52%%> and another here."
Output 3:
ConvertFormula(2) + "This is something completely different with the object call at the start." + ConvertFormula(52) + " and another here."
Example 4:
"There's nothing in this one, no code to find. Just has some text."
Output 4:
"There's nothing in this one, no code to find. Just has some text."
Example 5:
"This one goes on for a while, like 5132854123 characters, then has a single call right here.<%TABLE#112%%>"
Output 5:
"This one goes on for a while, like 5132854123 characters, then has a single call right here." + ConvertFormula(112)
Example 6:
"Short <%TABLE#412%%> one."
Output 6:
"Short " + ConvertFormula(412) + " one."
Example 7:
"Nothing here again."
Output 7:
"Nothing here again."
I'm guessing that this expression might simply work,
<%TABLE#([0-9]+)%%>
which we would use a capturing group and collect our desired IDs.
Demo
Test
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = #"<%TABLE#([0-9]+)%%>";
string input = #"<%TABLE#3%%>
<%TABLE#1213%%>";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(input, pattern, options))
{
Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
}
}
}
I will do work with asp.net C#. when I create runtime string (dynamic). After the string, I try to pass the data in the place of data row but I have no idea about that so please provide a proper solution.
Below is my code (code with example )
protected string Replace_Tag(string Email_msg)
{
try {
}
return Email_msg ;
}
After execute this function result found below. (return below string)
"View your all the details" + drmail["WorkName"].ToString() +
"this task is working " + drmail["Cjworkmode"].ToString() + "- " +
drmail["Cjtimeperiod"].ToString() + " "
This is the string so how can I execute this string in for loop and get the proper data.
For loop
string cast_data = Replace_Tag(EditorEmail.Content);
foreach (DataRow drmail in Get_Tab_Data().Tables[0].Rows)
{
String Vie_Data = cast_data;
}
In this for loop how to get below result.
View your all the details XYZ this task is working ABC - 2018
View your all the details ABC this task is working ABC - 2019
View your all the details EFG this task is working MZP - 2017
This is a principle called "string templating". Do some research to find existing solutions. If you don't want to use existing solutions, roll your own.
You could do so by introducing placeholders in the template string:
var templateString = "View all the details {WorkName} this task is working {Cjworkmode} - {Cjtimeperiod}";
Not to be confused with string interpolation, as these placeholders aren't known at compile time.
Then, for example using a regular expression, find all matches in the string:
var placeHolderRegEx = new Regex(#"(\{([a-z]+)\})", RegexOptions.IgnoreCase);
// Copy the string to be templated
var output = templateString;
foreach (Match match in placeHolderRegEx.Matches(templateString))
{
// Replace each instance of `{x}` with the value of `drmail[x]`.
output = output.Replace(match.Groups[1].Value, drmail[match.Groups[2].Value]);
}
I am working on a project that involves having to manipulate a bat file based on certain user produced parameters. The bat files themselves are created manually, with a static format. A basic example of a bat file would be:
cd \some\predefined\bat
start run_some_script "user_generated_argument" [other pre-defined arguments]
The "user_generated_argument" bit of the bat file is manipulated in C# by the following code:
string bat_text = File.ReadAllText(bat_path);
Regex regex = new Regex("(.*?)\".*\"(.*)");
string new_argument = "A new argument";
string new_bat = regex.Replace(bat_text , "$1\"" + new_argument + "\"$2", 1);
And that would produce the following:
cd \some\predefined\bat
start run_some_script "A new argument" [other pre-defined arguments]
which is the expected output.
However, the problem lies when one of the other pre-defined arguments after the first quoted argument is also in quotes when that is the case, it seems that the second quoted argument disappears. For example, if the bat file looks like:
cd \some\predefined\bat
start run_some_script "user_generated_argument" "a_predefined_quoted_argument" [other pre-defined arguments]
Running the same C# code from above would produce the following:
cd \some\predefined\bat
start run_some_script "A new argument" [other pre-defined arguments]
The "a_predefined_quoted_argument" would no longer be in the string.
I may be doing this completely wrong. How would I make the predefined quoted argument not disappear?
the problem is that your expression
\".*\"
is eager or greedy, taking everything between the first quote and the last quote it finds. To make it lazy or reluctant, put a ? after the *
like so (I used VB, which escapes double quotes by double double quotes)
Dim batfile As String = "cd \some\predefined\bat" & vbCrLf & "start run_some_script ""user_generated_argument"" ""a_predefined_quoted_argument"" [other pre-defined arguments]"
Dim regex As Regex = New Regex("(.*?)"".*?""(.*)")
Dim new_argument As String = "A new argument"
Dim new_bat As String = regex.Replace(batfile, "$1""" + new_argument + """ $2", 1)
It will now take everything between the first quote, and the next quote.
Instead of using Regex you could also read the lines with File.ReadAllLines(), take the desired line and split it with string.Split() and replace them in that way.
Something like:
string[] lines = File.ReadAllLines(fileName);
string commandLine = lines.Where(d => d.StartsWith("start")).Single();
string[] arguments = commandLine.Split(' ');
foreach (var argument in arguments)
{
if (argument.StartsWith("\""))
{
// do your stuff and reassemble
}
}
I'm trying to have a MessageBox appear that shows the changelog inside my C# program
This is the text file.
Current Version 0.2.3.4
Added Hash decoder
Attempted to change code into OOP design
Cleaned up random code with ReSharper
Version 0.1.3.4 - 8/29/2016
No change logs before this point
The goal is to get the text between Current Version 0.2.3.4 and Version 0.1.3.4 - 8/29/2016
I've had tried doing this with the code below
Regex changeLogMatch = new Regex("Current Version\\s.*?\\n(.*?\\n)+Version\\s.*?\\s\\-\\s\\d");
Match changeLogInfo = changeLogMatch.Match(changeLog);
int changeLogCount = Regex.Matches(changeLog, "Current Version\\s.*?\\n(.*?\\n)+Version\\s.*?\\s\\-\\s\\d").Count;
List<string> changeLogList = new List<string>();
for (int i = 0; i < changeLogCount; i++)
{
changeLogList.Add(changeLogInfo.Groups[1].Captures[i].ToString());
}
string changeLogString = string.Join(Environment.NewLine, changeLogList);
Console.WriteLine(changeLogString);
MessageBox.Show("New Changes" + Environment.NewLine + changeLogString
, "New Version Found: " + newVersion);
The issue I'm having is that changeLogString only displays Added Hash decoder and nothing else.
Any ideas on what I'm doing wrong?
In your case changeLogCount always be 1. So in changeLogList will be always changeLogInfo.Groups[1].Captures[0].ToString() what is refers to Added Hash decoder string.
You are checking for "Current Version\\s.*?\\n((.*?\\n)+)Version\\s.*?\\s\\-\\s\\d" regex, it is matching the whole string and matches 1 time. But the first group (.*?\\n) matches 3 times. So, if you are checking for count of matches of full regex - you will get 1, if you want to get number of captures of first group - you will get 3.
So you should fix your code in the following manner:
Regex changeLogMatch = new Regex("Current Version\\s.*?\\n(.*?\\n)+Version\\s.*?\\s\\-\\s\\d");
Match changeLogInfo = changeLogMatch.Match(changeLog);
string changeLogString = string.Join(Environment.NewLine, changeLogInfo.Groups[1].Captures.OfType<Capture>());
Console.WriteLine(changeLogString);
Note, that you have no need to iterate through captures - the required string will be stored in changeLogString.
I have tried to do some research, but everything that I find does not cover what my current dilemma is.
String manipulation is basic right? But here is my problem, I am grabbing an email body from gmail, the body looks something like this (after removing all the HTML formatting, and is a constant string):
Name : Testy Von Test
Cell 1111111111
email testy#testy
Now I need to find the string "Name" and then use trimming to get the full name, but how do I distinguish between this? how do I tell my coding to look for everything from name until Cell and take everything from there? I really did try to find the solution as I believe I am just missing some logic in my mind. If you just give me a link to an article I will be happy to read up and apply the logic myself (I am not expecting anyone to do my work for me), I just need a proper nudge in the right direction please.
Thank you kindly in advance.
(as an edit if anyone should follow this question, look at all the answers, there are a bunch of amazing answers and ideas)
The string you have doesn't seem very well formatted. Name is followed by a colon, Cell is not... this could get very tricky...
but a simple solution using substring.
var s = "Name : Testy Von Test Cell 1111111111 email testy#testy";
var name = s.Substring(
s.IndexOf(":")+1,
s.IndexOf("Cell")-s.IndexOf(":")-1);
Is your mail body always in the exact format?
You can for instance do as shown in this jsfiddle.
var mailbody = 'Name : Testy Von Test Cell 1111111111 email testy#testy';
var nameregex = /Name(.+?)Cell/
var match = nameregex.exec(mailbody);
console.log(match[1]); // Outputs " : Testy Von Test "
In your example it would capture, as seen in the console input, " : Testy von test ". And you can then manipulate it however you'd like. You can also modify the regex with additional options, depending on how your mail outputs vary.
var mailbody = 'Name : Testy Von Test Cell 1111111111 email testy#testy';
var nameregex = /Name\s:\s(.+?)\sCell/
var match = nameregex.exec(mailbody);
console.log(match[1]); // Outputs "Testy Von Test"
What about this:
int start = myString.IndexOf("Name") + "Name : ".Length;
int len = myString.IndexOf("Cell") - start;
string res = myString.Substring(start, len);
Alternativly via Regex:
Regex r = new Regex("Name(.*)Cell");
string res = r.Matches[0].Value;