I am searching for a long time on net. But no use. Please help or try to give some ideas how to achieve this.
In my SQL Database, have a data:
Reason:%s与%s等预算科目的内容存在重复,核减%d万元
ResultS1:本科目镍铁中多元素样品前处理
ResultS2:本科目ICP测定法
ResultD:2.50
I want get a string:本科目镍铁中多元素样品前处理与本科目ICP测定法等预算科目的内容存在重复,核减2.50万元
You can use the helpful extension method from this question (second answer down) ReplaceFirst:
public static string ReplaceFirst(this string text, string search, string replace)
{
int pos = text.IndexOf(search);
if (pos < 0)
{
return text;
}
return $"{text.Substring(0, pos)}{replace}{text.Substring(pos + search.Length)}";
}
and then call it like this
var reason = "%s与%s等预算科目的内容存在重复,核减%d万元";
var results1 = "本科目镍铁中多元素样品前处理";
var results2 = "本科目ICP测定法";
var resultd = "2.50";
var final = reason
.ReplaceFirst("%s", results1)
.ReplaceFirst("%s", results2)
.ReplaceFirst("%d", resultd);
Where final is assigned
"本科目镍铁中多元素样品前处理与本科目ICP测定法等预算科目的内容存在重复,核减2.50万元"
SELECT concat_ws('',ResultS1,'与',ResultS2,'等预算科目的内容存在重复,核减',ResultD,'万元') as Result
FROM `yourtable`
Follow the answer concatenate string in c#
string key = String.Join("", new String[] { ResultS1,'与',ResultS2,'等预算科目的内容存在重复,核减',ResultD,'万元'});
Related
private string trdoc(string str)
{
var listOfActions = new List<Action>();
string alltrdoc = "";
string doc = str;
var alldoc = doc.Split('\n');
foreach(string tt in alldoc)
{
//alltrdoc = alltrdoc + translate(tt) + '\n';//I can get the translated sentences in order but it's not multithread so it is slow.
listOfActions.Add(() => alltrdoc = alltrdoc + translate(tt) + '\n');//I can't get the translated sentences in order.
}
int paral = 4;
if (paral <= 0) { paral = 4; }
var options = new ParallelOptions { MaxDegreeOfParallelism = paral };
Parallel.Invoke(options, listOfActions.ToArray());
saveposcdic();
return alltrdoc;
}
translate(tt) should produce translated string.
I've been trying to make a translator. I came across this problem.
If I use the code without, task or parallel.invoke, then I get the document translated in the right order. However if I run the parallel.invoke like above, I will get the sentences in messed up order.
How can I get the translated documents in the right order using task or parallel.invoke?
I thought about adding the translated sentences in the list with numbers then sort the list when all tasks are completed then split the sentences and rearrange them but I think there has got to be a better way.
Code below works but it's not parallel.
private string trdoc(string str)
{
string alltrdoc = "";
string doc = str;
var alldoc = doc.Split('\n');
Task t = Task.Factory.StartNew(() => {
foreach (string tt in alldoc)
{
alltrdoc = alltrdoc + translate(tt) + '\n';
}
});
t.Wait();
saveposcdic();
return alltrdoc;
}
Enigmativity is right. You need to work cautiously with parallelism.
You may delegete it to linq.
var translatedStrings = alldoc
.AsParallel()
.WithDegreeOfParallelism(paral)
.AsOrdered()
.Select(tt => translate(tt));
var alltrdoc = string.Join("\n", translatedStrings);
Here there are two key methods:
AsParallel which makes select executes parallel and AsOrdered which will keep original order of lines.
Your second trdoc implementation isn't parallel because you put all the work in one task. It's like running Parallel.Invoke with only one Action
I suspect that you're not capturing the loop variable in your closure. Try changing your loop to be like this:
foreach (string tt in alldoc)
{
string local_tt = tt;
listOfActions.Add(() => alltrdoc = alltrdoc + translate(local_tt) + '\n');
}
The other issue you have is that you're trying to update the single value of alltrdoc using multiple threads. It's not going to work like that. You really should consider refactoring this code.
You're better off writing your entire method like this:
private string trdoc(string str)
{
return String.Join(Environment.NewLine, str.Split('\n').AsParallel().Select(x => translate(x)));
}
private string trdoc(string str)
{
var alldoc = str.Split('\n');
string[] alltrdoc1 = new string[alldoc.Length];
Parallel.For(0, alldoc.Length,
index => {
alltrdoc1[index] = translate(alldoc[index]);
});
string alltrdoc = string.Join("\n", alltrdoc1);
saveposcdic();
return alltrdoc;
}
I've got it working with this code. All the sentences are showing in the right order. I still don't know why Enigmativity's answer didn't work as intended.
If i have string like this:
string a = "<=1.0.5" or "=1.0.5" or "!=1.0.5";
How can i get the part with operator and the part with version number separately into variables?
Some kind of regex:
var str = "=1.0.5";
var regex = new Regex("([<>=!]+)(.*)");
var result = regex.Match(str);
Console.WriteLine(result.Groups[1].Value);
Console.WriteLine(result.Groups[2].Value);
If equal operator always present in the string:
string a = "<=1.0.5"; // "=1.0.5" or "!=1.0.5" or "==1.0.5"
int indx = a.LastIndexOf('=') + 1;
string op = a.Substring(0, indx); //<=
string version = a.Substring(indx); //1.0.5
I've stored all URLs in my application with "http://" - I now need to go through and replace all of them with "https:". Right now I have:
foreach (var link in links)
{
if (link.Contains("http:"))
{
/// do something, slice or replace or what?
}
}
I'm just not sure what the best way to update the string would be. How can this be done?
If you're dealing with uris, you probably want to use UriBuilder since doing a string replace on structured data like URIs is not a good idea.
var builder = new UriBuilder(link);
builder.Scheme = "https";
Uri modified = builder.Uri;
It's not clear what the type of links is, but you can create a new collection with the modified uris using linq:
IEnumerable<string> updated = links.Select(link => {
var builder = new UriBuilder(link);
builder.Scheme = "https";
return builder.ToString();
});
The problem is your strings are in a collection, and since strings are immutable you can't change them directly. Since you didn't specify the type of links (List? Array?) the right answer will change slightly. The easiest way is to create a new list:
links = links.Select(link => link.Replace("http://","https://")).ToList();
However if you want to minimize the number of changes and can access the string by index you can just loop through the collection:
for(int i = 0; i < links.Length; i++ )
{
links[i] = links[i].Replace("http://","https://");
}
based on your current code, link will not be replace to anything you want because it is read only (see here: Why can't I modify the loop variable in a foreach?). instead use for
for(int a = 0; a < links.Length; a++ )
{
links[a] = links[a].Replace("http:/","https:/")
}
http://myserver.xom/login.aspx?returnurl=http%3a%2f%2fmyserver.xom%2fmyaccount.aspx&q1=a%20b%20c&q2=c%2b%2b
What about the urls having also url in the querystring part? I think we should also replace them. And because of the url encoding-escaping this is the hard part of the job.
private void BlaBla()
{
// call the replacing function
Uri myNewUrl = ConvertHttpToHttps(myOriginalUrl);
}
private Uri ConvertHttpToHttps(Uri originalUri)
{
Uri result = null;
int httpsPort = 443;// if needed assign your own value or implement it as parametric
string resultQuery = string.Empty;
NameValueCollection urlParameters = HttpUtility.ParseQueryString(originalUri.Query);
if (urlParameters != null && urlParameters.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (string key in urlParameters)
{
if (sb.Length > 0)
sb.Append("&");
string value = urlParameters[key].Replace("http://", "https://");
string valuEscaped = Uri.EscapeDataString(value);// this is important
sb.Append(string.Concat(key, "=", valuEscaped));
}
resultQuery = sb.ToString();
}
UriBuilder resultBuilder = new UriBuilder("https", originalUri.Host, httpsPort, originalUri.AbsolutePath);
resultBuilder.Query = resultQuery;
result = resultBuilder.Uri;
return result;
}
Use string.Replace and some LINQ:
var httpsLinks = links.Select(l=>l.Replace("http://", "https://");
I have strings and each contain a value of RowKey stored like this:
data-RowKey=029
This occurs only once in each file. Is there some way I can get the number out with a C# function or do I have to write some kind of select myself. I have a team mate who suggested linq but I'm not sure if this even works on strings and I don't know how I could use this.
Update:
Sorry I changed this from file to string.
Linq does not really help you here. Use a regular expression to extract the number:
data-Rowkey=(\d+)
Update:
Regex r = new Regex(#"data-Rowkey=(\d+)");
string abc = //;
Match match = r.Match(abc);
if (match.Success)
{
string rowKey = match.Groups[1].Value;
}
Code:
public string ExtractRowKey(string filePath)
{
Regex r = new Regex(#"data-Rowkey=(\d+)");
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Match match = r.Match(line);
if (match.Success) return match.Groups[1].Value;
}
}
}
Assuming that it only exists once in a file, i would even throw an exception otherwise:
String rowKey = null;
try
{
rowKey = File.ReadLines(path)
.Where(l => l.IndexOf("data-RowKey=") > -1)
.Select(l => l.Substring(12 + l.IndexOf("data-RowKey=")))
.Single();
}
catch (InvalidOperationException) {
// you might want to log this exception instead
throw;
}
Edit: The simple approach with a string, take the first occurence which is always of length 3:
rowKey = text.Substring(12 + text.IndexOf("data-RowKey="), 3);
Assuming following
File must contain data-Row (with exact match including case)
Number length is 3
Following is the code snippet
var fileNames = Directory.GetFiles("rootDirPath");
var tuples = new List<Tuple<String, int>>();
foreach(String fileName in fileNames)
{
String fileData =File.ReadAllText(fileName) ;
int index = fileData.IndexOf("data-RowKey=");
if(index >=0)
{
String numberStr = fileData.Substring(index+12,3);// ASSUMING data-RowKey is always found, and number length is always 3
int number = 0;
int.TryParse(numberStr, out number);
tuples.Add(Tuple.Create(fileName, number));
}
}
Regex g = new Regex(#"data-RowKey=(?<Value>\d+)");
using (StreamReader r = new StreamReader("myFile.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
Match m = g.Match(line);
if (m.Success)
{
string v = m.Groups["Value"].Value;
// ...
}
}
}
RETURN (REPLACE(REPLACE(REPLACE(#input, #class_text, '~~|~'), #id_text, #class_text), '~~|~', #id_text))
where #input is string.
How to convert this in C# with the same parameters...
#class_text is class_text in C#, etc..
input = input.Replace(class_text, "~~|~").Replace(id_text, class_text).Replace("~~|~", id_text);
simple as that
T-SQL's REPLACE actually has different arguments. E.g.,
REPLACE(string1, string2, replaceText)
Where it is searching for string1 within string2, whereas, it is generally:
string1.Replace(string2, replaceText)
...in .NET, where you are searching for string2 in string1. For large amounts of string replaces, I'd recommend the StringBuilder.
var builder = new Stringbuilder(input);
builder = builder.Replace(class_text, "~~|~").Replace(id_text, class_text).Replace("~~|~", id_text)
string result = builder.ToString();
1) make a string
String myOldString = "No way";
2) Use the replace function
String myNewString = myOldString.Replace("No", "Yes");
Here's the MSDN for more detailed information: http://msdn.microsoft.com/en-us/library/fk49wtc1.aspx#Y480
EDIT
Here's the data from your post:
String myInput = "whatever #input equals"
String myclass_text = "whatever #class_text equals"
String myid_text = "whatever #id_text equals"
String myString = myInput.replace(myclass_text, "~~|~")
myString = myString.replace(myid_text, class_text)
myString = myString.replace("~~|~", myid_text)
Or all-in-one (I don't know if c# lets you piggy-back like this, but if prefer one-liners, give it a try:
String myString = myInput.replace(myclass_text, "~~|~").replace(myid_text, myclass_text).replace("~~|~", myid_text)
Converted the TSQL to C#, which could have been requested in original question How to change string element position in C#
/// <summary>
/// Given a line of text, swap position of class and id tags.
/// Id should always precede class tag
///
/// </summary>
/// <param name="input"><td class="m92_t_col5" id="preis_0">xx</td></param>
/// <returns><td id="preis_0" class="m92_t_col5">xx</td></returns>
public static string SwapClassAndId(string input)
{
string output = string.Empty;
int classOrdinal = 0;
int classOridnalEndQuotes = 0;
string classText = string.Empty;
int idOrdinal = 0;
int idOrdinalEndQuotes = 0;
string idText = string.Empty;
classOrdinal = input.IndexOf("class=");
classOridnalEndQuotes = input.IndexOf("\"", classOrdinal + 7) + 1;
idOrdinal = input.IndexOf("id=");
idOrdinalEndQuotes = input.IndexOf("\"", idOrdinal + 4) + 1;
if (idOrdinal < classOrdinal)
{
return input;
}
classText = input.Substring(classOrdinal, classOridnalEndQuotes - classOrdinal);
idText = input.Substring(idOrdinal, idOrdinalEndQuotes - idOrdinal);
output = input.Replace(classText, "~~|~").Replace(idText, classText).Replace("~~|~", idText);
return output;
}