Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
By using RegEx, or String.Replace, I need to replace any number of consecutive #'s (with the appropriate number of leading 0's) with an integer. I know I can search for # in the string, get the First and Last index, Last-First for the length, then replace with String.Replace. I was hoping someone would have a faster, and more slick answer.
Method header would be:
string ReplaceHashtagsWithInt(string input, int integer)
Examples:
Input -> "String####_Hi##", 2
Output -> "String0002_Hi02"
Input -> "String####_Hi##", 123
Output -> "String0123_Hi123"
public static class Testing
{
public static void Main()
{
ReplaceHashtagsWithInt("String####_Hi##", 2);
ReplaceHashtagsWithInt("String####_Hi###", 123);
ReplaceHashtagsWithInt("String####_Hi#######", 123);
}
public static string ReplaceHashtagsWithInt(string input, int integer)
{
Regex regex = new Regex("#+");
var matches = regex.Matches(input).Cast<Match>().Select(m => m.Value).ToArray();
Array.Sort(matches);
Array.Reverse(matches);
foreach (string match in matches)
{
Regex r = new Regex(match);
string zeroes = new string('0', match.Length - integer.ToString().Length) + integer;
input = r.Replace(input, zeroes);
}
return input;
}
}
You can do something like this:
using System;
using System.Text;
using System.Text.RegularExpressions;
public static class Testing
{
public static void Main()
{
Console.WriteLine(ReplaceHashtagsWithInt("###_####_#", 1));
Console.WriteLine(ReplaceHashtagsWithInt("###_####_#", 23));
Console.WriteLine(ReplaceHashtagsWithInt("###_####_#", 456));
Console.WriteLine(ReplaceHashtagsWithInt("###_####_#", 7890));
Console.WriteLine(ReplaceHashtagsWithInt("###_####_#", 78901));
}
public static string ReplaceHashtagsWithInt(string input, int integer)
{
Regex regex = new Regex("#+");
StringBuilder output = new StringBuilder(input);
int allig = 0;
for(Match match = regex.Match(input);match.Success;match = match.NextMatch())
{
string num = integer.ToString();
if(num.Length<=match.Length)
for(int i=0;i<match.Length;i++)
{
if(i<match.Length-num.Length)
output[match.Index+i+allig] = '0';
else
output[match.Index+i+allig] = num[i-match.Length+num.Length];
}
else
{
output.Remove(match.Index+allig,match.Length);
output.Insert(match.Index+allig,num);
allig+=num.Length-match.Length;
}
}
return output.ToString();
}
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have text file like this:
VehicleReferenceKey:2365565656
DriverReferenceKey:965454545454
Latitude:30000
**
VehicleReferenceKey:96896A4607A6
DriverReferenceKey:96896A4607A6
Latitude:500
**
VehicleReferenceKey:822F5B18
DriverReferenceKey:822F5B18
Latitude:1000
I try To convert this text file to Excel
first i made an Class as
public class Item
{
public string VehicleReferenceKey;
public string DriverReferenceKey;
public string Latitude;
}
then i read all text file and looping of it as
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}
but I Can't determine how i can specify the Key and value
for each line , and how tell the sign
**
as it's breaker between each object .Any Help
Try following code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication87
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
Item items = new Item(FILENAME);
}
}
public class Item
{
public static List<Item> items = new List<Item>();
public string VehicleReferenceKey;
public string DriverReferenceKey;
public string Latitude;
public Item() { }
public Item(string filenam)
{
StreamReader reader = new StreamReader(filenam);
string line = "";
Item newItem = null;
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
string[] rowItems = line.Split(new char[] { ':' });
switch (rowItems[0])
{
case "VehicleReferenceKey" :
newItem = new Item();
items.Add(newItem);
newItem.VehicleReferenceKey = rowItems[1];
break;
case "DriverReferenceKey":
newItem.DriverReferenceKey = rowItems[1];
break;
case "Latitude":
newItem.Latitude = rowItems[1];
break;
}
}
}
}
}
}
Basically it seems the following hold for your file:
The first item takes 3 lines (one for each field)
Every item after the first takes 7 lines (2 empty lines, 1 line containing "**", 1 empty line and then the 3 lines with the field values)
So there's no reason to parse the ** and the empty lines you can just skip those (by looping over 7 lines at a time).
For the seperating key and value you can use the String.Split method.
All in all it would look something like this:
for (var i = 0; i < lines.Length + 2; i += 7)
{
var newItem = new Item(){
VehicleReferenceKey = lines[i].Split(':')[1],
DriverReferenceKey = lines[i+1].Split(':')[1],
Latitude = lines[i+2].Split(':')[1]
}
//do whatever you want with the newItem
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I want to take the following string as input:
first-arg second-arg "third arg with spaces" "arg with \" quotes"
and return this list of strings as output
["first-arg", "second-arg", "third arg with spaces", "arg with \" quotes"]
Are there any nuget packages or built in functions that can do this? I want it to handle edge cases like arguments containing multiple words and arguments containing quotes.
string[] arguments = Environment.GetCommandLineArgs();
For more information see the MSDN website
This class satisfies the requirements. It's not the most effective way, but it returns the right arguments.
public static class ArgumentLineParser
{
public static string[] ToArguments(string cmd)
{
if (string.IsNullOrWhiteSpace(cmd))
{
return new string[0];
}
var argList = new List<string>();
var parseStack = new Stack<char>();
bool insideLiteral = false;
for (int i = 0; i < cmd.Length; i++)
{
bool isLast = i + 1 >= cmd.Length;
if (char.IsWhiteSpace(cmd[i]) && insideLiteral)
{
// Whitespace within literal is kept
parseStack.Push(cmd[i]);
}
else if (char.IsWhiteSpace(cmd[i]))
{
// Whitespace delimits arguments
MoveArgumentToList(parseStack, argList);
}
else if (!isLast && '\\'.Equals(cmd[i]) && '"'.Equals(cmd[i + 1]))
{
//Escaped double quote
parseStack.Push(cmd[i + 1]);
i++;
}
else if ('"'.Equals(cmd[i]) && !insideLiteral)
{
// Begin literal
insideLiteral = true;
}
else if ('"'.Equals(cmd[i]) && insideLiteral)
{
// End literal
insideLiteral = false;
}
else
{
parseStack.Push(cmd[i]);
}
}
MoveArgumentToList(parseStack, argList);
return argList.ToArray();
}
private static void MoveArgumentToList(Stack<char> stack, List<string> list)
{
var arg = string.Empty;
while (stack.Count > 0)
{
arg = stack.Pop() + arg;
}
if (arg != string.Empty)
{
list.Add(arg);
}
}
}
It can be used like this:
var line = #"first-arg second-arg ""third arg with spaces"" ""arg with \"" quotes""";
var args = ArgumentLineParser.ToArguments(line);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm working with a rather large set of strings I have to process as quickly as possible.
The format is quite fixed:
[name]/[type]:[list ([key] = [value],)]
or
[name]/[type]:[key]
I hope my representation is okay. What this means is that I have a word (in my case I call it Name), then a slash, followed by another word (I call it Type), then a colon, and it is either followed by a comma-separated list of key-value pairs (key = value), or a single key.
Name, Type cannot contain any whitespaces, however the key and value fields can.
Currently I'm using Regex to parse this data, and a split:
var regex = #"(\w+)\/(\w+):(.*)";
var r = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
var m = r.Match(Id);
if (m.Success) {
Name = m.Groups[1].Value;
Type= m.Groups[2].Value;
foreach (var intern in m.Groups[3].Value.Split(','))
{
var split = intern.Trim().Split('=');
if (split.Length == 2)
Items.Add(split[0], split[1]);
else if (split.Length == 1)
Items.Add(split[0], split[0]);
}
}
Now I know this is not the most optional case, but I'm not sure which would be the fastest:
Split the string first by the : then by / for the first element, and , for the second, then process the latter list and split again by =
Use the current mixture as it is
Use a completely regex-based
Of course I'm open to suggestions, my main goal is to achieve the fastest processing of this single string.
Its always fun to implement a custom parser. Obviously concerning code maintenance, Regex is probably the best choice, but if performance is an ultimate concern then you probably need a tailor made parser which even in the simplest syntaxes is quite a lot more of work.
I've whipped one up really quick (it might be a little hackish in some places) to see what it would take to implement one with some basic error recovery and information. This isn't tested in any way but I'd be curious, if its minimally functional, to know how well it stacks up with the Regex solution in terms of performance.
public class ParserOutput
{
public string Name { get; }
public string Type { get; }
public IEnumerable<Tuple<string, string>> KeyValuePairs { get; }
public bool ContainsKeyValuePairs { get; }
public bool HasErrors { get; }
public IEnumerable<string> ErrorDescriptions { get; }
public ParserOutput(string name, string type, IEnumerable<Tuple<string, string>> keyValuePairs, IEnumerable<string> errorDescriptions)
{
Name = name;
Type = type;
KeyValuePairs = keyValuePairs;
ContainsKeyValuePairs = keyValuePairs.FirstOrDefault()?.Item2?.Length > 0;
ErrorDescriptions = errorDescriptions;
HasErrors = errorDescriptions.Any();
}
}
public class CustomParser
{
private const char forwardSlash = '/';
private const char colon = ':';
private const char space = ' ';
private const char equals = '=';
private const char comma = ',';
StringBuilder buffer = new StringBuilder();
public ParserOutput Parse(string input)
{
var diagnosticsBag = new Queue<string>();
using (var enumerator = input.GetEnumerator())
{
var name = ParseToken(enumerator, forwardSlash, diagnosticsBag);
var type = ParseToken(enumerator, colon, diagnosticsBag);
var keyValuePairs = ParseListOrKey(enumerator, diagnosticsBag);
if (name.Length == 0)
{
diagnosticsBag.Enqueue("Input has incorrect format. Name could not be parsed.");
}
if (type.Length == 0)
{
diagnosticsBag.Enqueue("Input has incorrect format. Type could not be parsed.");
}
if (!keyValuePairs.Any() ||
input.Last() == comma /*trailing comma is error?*/)
{
diagnosticsBag.Enqueue("Input has incorrect format. Key / Value pairs could not be parsed.");
}
return new ParserOutput(name, type, keyValuePairs, diagnosticsBag);
}
}
private string ParseToken(IEnumerator<char> enumerator, char separator, Queue<string> diagnosticsBag)
{
buffer.Clear();
var allowWhitespaces = separator != forwardSlash && separator != colon;
while (enumerator.MoveNext())
{
if (enumerator.Current == space && !allowWhitespaces)
{
diagnosticsBag.Enqueue($"Input has incorrect format. {(separator == forwardSlash ? "Name" : "Type")} cannot contain whitespaces.");
}
else if (enumerator.Current != separator)
{
buffer.Append(enumerator.Current);
}
else
return buffer.ToString();
}
return buffer.ToString();
}
private IEnumerable<Tuple<string, string>> ParseListOrKey(IEnumerator<char> enumerator, Queue<string> diagnosticsBag)
{
buffer.Clear();
var isList = false;
while (true)
{
var key = ParseToken(enumerator, equals, diagnosticsBag);
var value = ParseToken(enumerator, comma, diagnosticsBag);
if (key.Length == 0)
break;
yield return new Tuple<string, string>(key, value);
if (!isList && value.Length != 0)
{
isList = true;
}
else if (isList && value.Length == 0)
{
diagnosticsBag.Enqueue($"Input has incorrect format: malformed [key / value] list.");
}
}
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In C# I'm trying to search for the substring "flight%sin" where %s would be a string. How would I do this using regex in c#?
You can capture the text between "flight" and "in" using #"flight(\w+)in"
The reference guide provides more detail.
Here is a Regex example in C#.
string [] mystrings = new string [] {"flight%sin", "flightTest1sin", "flighNoGoodsin", "flightTest2sin"};
foreach (string s in mystrings)
{
var groups = Regex.Match(s, #"flight(\w+)in");
if (groups.Groups.Count > 1)
{
Console.WriteLine(groups.Groups[1]);
}
}
Console.ReadKey();
Does this help?
string data = "flight 4057 in"; //I am guessing, this is what the original string will be.
public string getFlightNumber(string data)
{
int flightNumLength = 4;// Or however long the string would be
for(int index = 0; index < data.length(); index++)
{
if(index+flightNumLength + index < data.length())
{
string TempFlight = data.subSting(index, flightNumLength);
if(isNumeric(TempFlight))
{
return TempFlight;
}
}
}
}
public static bool IsNumeric(object Expression){
bool isNum;
double retNum;
isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any,System.Globalization.NumberFormatInfo.InvariantInfo, out retNum );
return isNum;
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Regular expression, split string by capital letter but ignore TLA
I have a string which is a combination of several words, each word is capitalized.
For example: SeveralWordsString
Using C#, how do I split the string into "Several Words String" in a smart way?
Thanks!
Use this regex (I forgot from which stackoverflow answer I sourced it, will search it now):
public static string ToLowercaseNamingConvention(this string s, bool toLowercase)
{
if (toLowercase)
{
var r = new Regex(#"
(?<=[A-Z])(?=[A-Z][a-z]) |
(?<=[^A-Z])(?=[A-Z]) |
(?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);
return r.Replace(s, "_").ToLower();
}
else
return s;
}
I use it in this project: http://www.ienablemuch.com/2010/12/intelligent-brownfield-mapping-system.html
[EDIT]
I found it now: How do I convert CamelCase into human-readable names in Java?
Nicely split "TodayILiveInTheUSAWithSimon", no space on front of " Today":
using System;
using System.Text.RegularExpressions;
namespace TestSplit
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
var r = new Regex(#"
(?<=[A-Z])(?=[A-Z][a-z]) |
(?<=[^A-Z])(?=[A-Z]) |
(?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);
string s = "TodayILiveInTheUSAWithSimon";
Console.WriteLine( "YYY{0}ZZZ", r.Replace(s, " "));
}
}
}
Output:
YYYToday I Live In The USA With SimonZZZ
string[] SplitCamelCase(string source) {
return Regex.Split(source, #"(?<!^)(?=[A-Z])");
}
Sample:
https://dotnetfiddle.net/0DEt5m
You can just loop through the characters, and add spaces where needed:
string theString = "SeveralWordsString";
StringBuilder builder = new StringBuilder();
foreach (char c in theString) {
if (Char.IsUpper(c) && builder.Length > 0) builder.Append(' ');
builder.Append(c);
}
theString = builder.ToString();
public static IEnumerable<string> SplitOnCapitals(string text)
{
Regex regex = new Regex(#"\p{Lu}\p{Ll}*");
foreach (Match match in regex.Matches(text))
{
yield return match.Value;
}
}
This will handle Unicode properly.
string str1 = "SeveralWordsString";
string newstring = "";
for (int i = 0; i < str1.Length; i++)
{
if (char.IsUpper(str1[i]))
newstring += " ";
newstring += str1[i].ToString();
}