In string will be something like this:
for(I=1;I<10;I++) /*Else*/ {A = "for"; B = 'c'; break;} // while(a < 10)
I would like to remove from this string anything that is between /**/ and between "" and between '' and anything after //
Here is example
input:
for(I=1;I<10;I++) /*Else*/ {A = "for"; B = 'c'; break;} // while(a < 10)
output:
FOR(i=1;i<10;i++) /**/ {a = ""; b = ''; BREAK;} //
I know that I have to go through characters in string with:
for (int i = 0; i < input.Length; i++)
{
// search for /**/ ?
}
but i don't know how should I remove characters and put the other characters in new string.
string sentence = "for(I=1;I<10;I++) /*Else*/ {A = "for"; B = 'c'; break;} // while(a < 10)";
//how can I remove these characters from string so it will look something like this?
string shortSentence = "FOR(i=1;i<10;i++) /**/ {a = ""; b = ''; BREAK;} //";
Try this. The idea is to first remove the stuff at the end, the // comments. Then afterwards, we search for /* and the next /, remove that text (we are left with /**/, save the index of that string and remove it as well. Once we have no more / strings, we reinsert the /**/ into the positions we removed them from.
NOTE: This won't work if you have something like this /* comment /* more comment */ and some other part */. But this also isn't a valid comment in C#, which is the language you tagged here.
static string s = "for(int i = 0; i < 10; i++){ var myVar = \"Test\"; /*commented out code*/ Console.WriteLine(\"stuff\"); /* more comments here*/}//my comments here \n var myOverVar = /*more stuff removed*/ true; //some more comments";
static void Main(string[] args)
{
//s.IndexOf()
var result = new List<string>();
var lines = s.Split(new[] {"\n"}, StringSplitOptions.RemoveEmptyEntries); //use this if you have multiple code lines, separated by new lines.
foreach (var line in lines)
{
var listOfPositions = new List<int>();
var l = line;
//chop off everything after comments
var indexOfLineComment = l.IndexOf("//");
l = l.Remove(indexOfLineComment + 2); // 2 because // is two characters long
var openBraceIndex = l.IndexOf("/*");
while (openBraceIndex != -1) //-1 indicates that we didn't find /*
{
var closingBraceIndex = l.IndexOf("*/");
if (closingBraceIndex == -1)
{
break; //you didn't specify how to the case when an error in syntax was made, but handle it here
}
l = l.Remove(openBraceIndex + 2, closingBraceIndex - openBraceIndex-2);
var ind = l.IndexOf("/**/");
listOfPositions.Insert(0, ind);
l = l.Remove(ind, 4);
openBraceIndex = l.IndexOf("/*");
}
foreach (var i in listOfPositions)
if (l.Length <= i)
l = l + "/**/";
else
l = l.Insert(i, "/**/");
result.Add(l);
}
}
Related
I want to mix 2 string in 1 randomly using foreach but I don't know how I delete the part I used on the string for the foreach like:
string s = "idontknow";
string sNew = "";
foreach(char ss in s){
s = s + ss;
ss.Delete(s); //don't exist
}
Full code here i'm trying to do:
do
{
if (state == 0)
{
for (int i = 0; random.Next(1, 5) > variable.Length; i++)
{
foreach (char ch in variable)
{
fullString = fullString + ch;
}
}
state++;
}
else if (state == 1)
{
for (int i = 0; random.Next(1, 5) > numbers.Length; i++)
{
foreach (char n in numbers)
{
fullString = fullString + n;
}
}
state--;
}
} while (variable.Length != 0 && numbers.Length != 0);
I'm pretty confident, that in your first code snippet, you are creating an infinite loop, since you are appending the used char back to the string while removing it from the first position.
Regarding your specification to shuffle two stings together, this code sample might do the job:
public static string ShuffleStrings(string s1, string s2){
List<char> charPool = new();
foreach (char c in s1) {
charPool.Add(c);
}
foreach (char c in s2) {
charPool.Add(c);
}
Random rand = new();
char[] output = new char[charPool.Count];
for(int i = 0; i < output.Length; i++) {
int randomIndex = rand.Next(0, charPool.Count);
output[i] = charPool[randomIndex];
charPool.RemoveAt(randomIndex);
}
return new string(output);
}
In case you just want to shuffle one string into another string, just use an empty string as the first or second parameter.
Example:
string shuffled = ShuffleStrings("TEST", "string");
Console.WriteLine(shuffled);
// Output:
// EgsTtSnrTi
There are possibly other solutions, which are much shorter, but I think this code is pretty easy to read and understand.
Concerning the performance, the code above should works both for small stings and large strings.
Since strings are immutable, each modify-operation on any string, e.g. "te" + "st" or "test".Replace("t", ""), will allocate and create a new string in the memory, which is - in a large scale - pretty bad.
For that very reason, I initialized a char array, which will then be filled.
Alternatively, you can use:
using System.Text;
StringBuilder sb = new();
// append each randomly picked char
sb.Append(c);
// Create a string from appended chars
sb.ToString();
And if your question was just how to remove the first char of a string:
string myStr = "Test";
foreach (char c in myStr) {
// do with c whatever you want
myStr = myStr[1..]; // assign a substring exluding first char (start at index 1)
Console.WriteLine($"c = {c}; myStr = {myStr}");
}
// Output:
// c = T; myStr = est
// c = e; myStr = st
// c = s; myStr = t
// c = t; myStr =
I have an requirement like search functionality,
Edit: Search is like set of varchars usually this ID contains values like C001,C002,...
so if user is entering the ranges like C001-C010 it should search all the rows in oracle db in between that C001-C010 this is what my requirement.
If user is entering some ranges like C001-C010 in text box this should be splited as two variables and it should search all the elements in between this range.
How to do this. I think using Enumerator range we can do this but i am facing problem like splitting strings needs to declared as separate variable and search between that. which I cant achieve.
sample code is below.
else if (!_search.MultipleId.Contains('-'))
{
filterExp = filterExp.And(x => x.Id.Contains(_search.MultipleId));
}
If the Id is in format of CXXX then you can do something like this:
if(_search.MultipleId.Contain("-"))
{
var range = _search.MultipleId.Split('-');
filterExp = filterExp.And(x => x.Id >= range[0] && x.Id <= range1);
}
Not knowing all of you business requirements, you could try something like this:
class Program
{
static void Main(string[] args)
{
var items = new List<string> { "C001", "C010" };
var firstChar = new List<string>();
var remainingChars = new List<string>();
items.ForEach(i =>
{
firstChar.Add(i[0].ToString());
remainingChars.Add(i.Substring(1));
});
firstChar.ForEach(f => { Console.Write(f + " "); });
Console.WriteLine();
remainingChars.ForEach(r => { Console.Write(r + " "); });
Console.WriteLine();
//Prints the following
//C C
//001 010
//Press any key to continue . . .
}
}
Something like this might help:
var pair = yourstring.Split('-')
.Select(a => new { one= a[0], two= a[1]});
I would cast the dataset to a list so I could use the indices of the start and end args.
var items = dataset.ToList();
var searchString = "B1, C10";
var removedWhitespace = Regex.Replace(searchString, #"\s+", "");
var rangeToSearch = removedWhitespace.Split(',');
var startPosition = items.FindIndex(x => x.ID == rangeToSearch.First());
var endPosition = items.FindIndex(x => x.ID == rangeToSearch.Last());
var selectedItems =
items.Skip(startPosition).Take(endPosition - startPosition + 1); // +1 to include the original id's
If you have to you can order the list, but one caveat with this method is that the list is ordered alphabetically, so you may have to do some additional processing to make sure that you return all the values in the range.
public static HashSet<string> getIdsFromRangeQuery(string multipleIds)
{
multipleIds = multipleIds.ToUpper().Replace(" ", "");
HashSet<string> inSet = new HashSet<string>();
string[] parts = multipleIds.Split(new[] { ";" }, StringSplitOptions.None);
foreach (string part in parts)
{
Regex rgx = new Regex(#"^M([0 - 9] +)C([0 - 9] +)$");
Regex rgxTwo = new Regex(#"^M([0-9]+)C([0-9]+)-M([0-9]+)C([0-9]+)$");
Regex rgxThree = new Regex(#"^[0-9]+$");
Regex rgxFour = new Regex(#"^([0-9]+)-([0-9]+)$");
if (rgx.IsMatch(part))
{
inSet.Add(part);
}
else if (rgxTwo.IsMatch(part))
{
string[] fromTo = part.Split(new[] { "-" }, StringSplitOptions.None);
int mFrom = int.Parse(fromTo[0].Substring(1, fromTo[0].IndexOf("C")));
int mTo = int.Parse(fromTo[1].Substring(1, fromTo[1].IndexOf("C")));
int cFrom = int.Parse(fromTo[0].Substring(fromTo[0].LastIndexOf("C") + 1));
int cTo = int.Parse(fromTo[1].Substring(fromTo[1].LastIndexOf("C") + 1));
for (int i = mFrom; i <= mTo; i++)
{
for (int j = cFrom; j <= cTo; j++)
{
inSet.Add("M" + i + "C" + j);
}
}
}
else if (rgxThree.IsMatch(part))
{
inSet.Add(part);
}
else if (rgxFour.IsMatch(part)
{
string[] fromTo = part.Split(new[] { "-" }, StringSplitOptions.None);
int from = int.Parse(fromTo[0]);
int to = int.Parse(fromTo[1]);
for (int i = from; i <= to; i++)
{
inSet.Add(i.ToString());
}
}
else
{
inSet.Add(part);
}
}
return inSet;
}
Hello I'm having a little trouble on this one aspect in my code. I have some strings and I have a array of chars. I'm trying to replace the last two letters of each string
with the characters in the char array until the last one.
My array of char is as follows:
char[] array = { 'v', 'x', 'f' };
My code so far:
char[] array = { 'v', 'x', 'f' };
string newWord="";
string apple="apple";
string sam="sam";
foreach(char c in array)
{
apple= apple.Substring(0, apple.Length - 2) +""; ///DON'T KNOW WHAT TO PUT HERE;
sam= sam.Substring(0, sam.Length - 2)+""; ///DON'T KNOW WHAT TO PUT HERE;
newWord = apple+Environment.NewLine+sam ;
}
The output should like like this:
appvx
sfm
Maybe I'm doing this wrong but I'm explicitly telling it in the substring to get rid of the last to letters in the word but if the array runs out won't it still delete the last two. For instance the word sam still needs to have m at the end of it since all the chars in the array have already been used like what the out but shows but replace a with f
something like this?
private static void something()
{
List<char> tokens = new List<char>(new char[]{ 'v', 'x', 'f' });
List<char[]> lArr = new List<char[]>();
lArr.Add("apple".ToCharArray());
lArr.Add("sam".ToCharArray());
List<string> lStr = new List<string>();
int cnt = 2;
foreach (var token in tokens)
{
var aktArr = lArr.FirstOrDefault();
if (aktArr == null)
break;
if (cnt == 0)
{
cnt = 2;
lStr.Add(new string(aktArr));
lArr.RemoveAt(0);
aktArr = lArr.FirstOrDefault();
if (aktArr == null)
break;
}
aktArr[aktArr.Length - cnt--] = token;
}
lStr.AddRange(lArr.Select(x => new string(x)));
foreach (var item in lStr)
{
Console.WriteLine(item);
}
}
You can treat a string as an array of chars, so the result can be something like this (supposing that you have an array of words, not only 2 variables for them and a little helper to replace chars)
var words = new [] {"apple", "sam"};
var wordPos = 0;
for (int i = 0; i < array.Length; i++)
{
var wordLen = words[wordPos].Length;
var letterPos = i % 2 == 0 ? 1 : 2;
words[wordPos] = words[wordPos].ReplaceAt(wordLen - letterPos, letter);
if (letterPos == 1) wordPos++;
}
public static string ReplaceAt(this string input, int index, char newChar)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
char[] chars = input.ToCharArray();
chars[index] = newChar;
return new string(chars);
}
I think something like this will do what you need:
var charArray = new[] {'a', 'b', 'c'};
var words = new List<string> {"apple", "sam"};
var currentWord = 0;
var currentChar = 0;
var charsToReplace = 2;
while (currentChar < charArray.Length && currentWord != words.Count)
{
var word = words[currentWord].ToCharArray();
word[word.Length - charsToReplace] = charArray[currentChar];
words[currentWord] = new string(word);
charsToReplace--;
currentChar++;
if (charsToReplace == 0)
{
charsToReplace = 2;
currentWord++;
}
}
words.ForEach(Console.WriteLine);
I want to break a long String in c# without breaking a words
Example: S AAA BBBBBBB CC DDDDDD V Breaking Character on 7 Count:
S AAA
BBBBBBB
CC
DDDDDD
V
How do I do this?
string inputStr = "S AAA BBBBBBB CC DDDDDD V ";
int maxWordLength = 7;
char separator = ' ';
string[] splitted = inputStr.Split(new[]{separator}, StringSplitOptions.RemoveEmptyEntries);
var joined = new Stack<string>();
joined.Push(splitted[0]);
foreach (var str in splitted.Skip(1))
{
var strFromStack = joined.Pop();
var joindedStr = strFromStack + separator + str;
if(joindedStr.Length > maxWordLength)
{
joined.Push(strFromStack);
joined.Push(str);
}
else
{
joined.Push(joindedStr);
}
}
var result = joined.Reverse().ToArray();
Console.WriteLine ("number of words: {0}", result.Length);
Console.WriteLine( string.Join(Environment.NewLine, result) );
prints:
number of words: 5
S AAA
BBBBBBB
CC
DDDDDD
V
Here's a shorter solution harnessing the power of regular expressions.
string input = "S AAA BBBBBBB CC DDDDDD V";
// Match up to 7 characters with optional trailing whitespace, but only on word boundaries
string pattern = #"\b.{1,7}\s*\b";
var matches = Regex.Matches(input, pattern);
foreach (var match in matches)
{
Debug.WriteLine(match.ToString());
}
This does the trick if I've understood your question correctly. A recursive implementation would have been cooler, but tail recursion is too damn bad in C# :)
Could also be implemented with yield and IEnumerable<string>.
string[] splitSpecial(string words, int lenght)
{
// The new result, will be turned into string[]
var newSplit = new List<string>();
// Split on normal chars, ie newline, space etc
var splitted = words.Split();
// Start out with null
string word = null;
for (int i = 0; i < splitted.Length; i++)
{
// If first word, add
if (word == null)
{
word = splitted[i];
}
// If too long, add
else if (splitted[i].Length + 1 + word.Length > lenght)
{
newSplit.Add(word);
word = splitted[i];
}
// Else, concatenate and go again
else
{
word += " " + splitted[i];
}
}
// Flush what we have left, ie the last word
newSplit.Add(word);
// Convert into string[] (a requirement?)
return newSplit.ToArray();
}
Why not to try regex?
(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)
and use all captures.
C# code:
var text = "S AAA BBBBBBB CC DDDDDD V";
var matches = new Regex(#"(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)").Matches(text).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
foreach (var match in matches)
{
Console.WriteLine(match);
}
Output:
S AAA
BBBBBBB
CC
DDDDDD
V
string str = "S AAA BBBBBBB CC DDDDDD V";
var words = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
List<string> result = new List<string>();
for (int i = 0; i < words.Length; ++i)
{
if (sb.Length == 0)
{
sb.Append(words[i]);
}
else if (sb.Length + words[i].Length < 7)
{
sb.Append(' ');
sb.Append(words[i]);
}
else
{
result.Add(sb.ToString());
sb.Clear();
sb.Append(words[i]);
}
}
if (sb.Length > 0)
{
result.Add(sb.ToString());
}
Results will contain:
S AAA
BBBBBBB
CC
DDDDDD
V
The predicate can be adjusted depending on if the separator between words should be included in the 7 characters or not.
This is how to add row break to HTML text:
SplitLongText(string _SourceText, int _MaxRowLength)
{
if (_SourceText.Length < _MaxRowLength)
{
return _SourceText;
}
else
{
string _RowBreakText="";
int _CurrentPlace = 0;
while (_CurrentPlace < _SourceText.Length)
{
if (_SourceText.Length - _CurrentPlace < _MaxRowLength)
{
_RowBreakText += _SourceText.Substring(_CurrentPlace);
_CurrentPlace = _SourceText.Length;
}
else
{
string _PartString = _SourceText.Substring(_CurrentPlace, _MaxRowLength);
int _LastSpace = _PartString.LastIndexOf(" ");
if (_LastSpace > 0)
{
_RowBreakText += _PartString.Substring(0, _LastSpace) + "<br/>" + _PartString.Substring(_LastSpace, (_PartString.Length - _LastSpace));
}
else
{
_RowBreakText += _PartString + "<br/>";
}
_CurrentPlace += _MaxRowLength;
}
}
return _RowBreakText;
}
2021
Look at this extension method, it uses recursivity
public static string SubstringDontBreakWords(this string str, int maxLength)
{
return str.Length <= maxLength ? str : str.Substring(0, str.LastIndexOf(" ")).Trim().SubstringDontBreakWords(maxLength);
}
Use it like this
string text = "Hello friends";
text.SubstringDontBreakWords(10)
I have a file which contains lots of numbers which I want to reduce to construct a new file. First, I extract all the text using File.ReadAllText, then I split and extract numbers from each line that contains a number which are separated by commas or spaces. After scan, I replace all occurrences of each found number with the new reduced number but the problem is that this method is error prone since some numbers get replaced more than once
Here's the code I'm using:
List<float> oPaths = new List<float>();
List<float> nPaths = new List<float>();
var far = File.ReadAllText("paths.js");
foreach(var s in far.Split('\n'))
{
//if it starts with this that means there are some numbers
if (s.StartsWith("\t\tpath:"))
{
var paths = s.Substring(10).Split(new[]{',', ' '});
foreach(var n in paths)
{
float di;
if(float.TryParse(n, out di))
{
if(oPaths.Contains(di)) break;
oPaths.Add(di);
nPaths.Add(di * 3/4);
}
}
}
}
//second iteration to replace old numbers with new ones
var ns = far;
for (int i = 0; i < oPaths.Count; i++)
{
var od = oPaths[i].ToString();
var nd = nPaths[i].ToString();
ns = ns.Replace(od, nd);
}
File.WriteAllText("npaths.js", ns);
As you can see, the above method is redundant as it does not replace the strings on real time. Maybe my head is full, but I'm just lost on how to go about this. Any ideas?
Thanks.
I think a regex can help here
string text = File.ReadAllText(file);
string newtext = Regex.Replace(text, #"\b(([0-9]+)?\.)?[0-9]+\b", m =>
{
float f;
if (float.TryParse(m.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out f)) f *= 3.0f / 4;
return f.ToString();
});
File.WriteAllText(file, newtext);
Just after typing the question I realized the answer was to iterate character by character and replace accordingly. Here's the code I used to get this to work:
string nfar = "";
var far = File.ReadAllText("paths.js");
bool neg = false;
string ccc = "";
for(int i = 0; i < far.Length; i++)
{
char c = far[i];
if (Char.IsDigit(c) || c == '.')
{
ccc += c;
if (far[i + 1] == ' ' || far[i + 1] == ',')
{
ccc = neg ? "-" + ccc : ccc;
float di;
if (float.TryParse(ccc, out di))
{
nfar += (di*0.75f).ToString();
ccc = "";
neg = false;
}
}
}
else if (c == '-')
{
neg = true;
}
else
{
nfar += c;
}
}
File.WriteAllText("nfile.js", nfar);
Comments and/or optimization suggestions are welcome.