C# Splitting Strings on '#' Character

How to split string between different chars

You can use String.Split() method with params char[];

Returns a string array that contains the substrings in this instance
that are delimited by elements of a specified Unicode character array.

string text = "the dog :is very# cute";
string str = text.Split(':', '#')[1]; // [1] means it selects second part of your what you split parts of your string. (Zero based)
Console.WriteLine(str);

Here is a DEMO.

You can use it any number of you want.

Separating two strings if any character is encountered

try this:

string MyString="www.myurl.com/help,mycustomers";
string first=MyString.Split(',')[0];
string second=MyString.Split(',')[1];

If MyString contains multiple parts, you can use:

string[] CS = MyString.Split(',');

And each parts can be accessed like:

CS[0],CS[1],CS[2]

For example:

 string MyString="www.myurl.com/help,mycustomers,mysuppliers";
string[] CS = MyString.Split(',');
CS[0];//www.myurl.com/help
CS[1];//mycustomers
CS[2];//mysuppliers

If you want to know more about Split function. Read this.

Can String.Split differentiate between a single instance and multiple instances of a char?

You can use Regex.Split:

 var parts = Regex.Split(source, @"(?=^#[^#])", RegexOptions.Multiline);

where:

  • (?= ... ) matches anything inside the parenthesis as lookahead (including it with the result, rather than discarding it as delimiter)
  • ^ with RegexOptions.Multiline represents a start-of-line anchor
  • #[^#] matches a hash followed by a non-hash character

In line with Split semantics, the first string in the returned array will be the substring occurring before the first section header. For your example, this would be an empty string, which you presumably want to discard.

RegEx: Split string by separator and then by another

This regex (.*?)\$\$(.*?)(?:\^|$) will match the name value pairs, and here is a Rubular to prove it. And to use it you can use the following code:

var input = "name1$$value1^name2$$value2^name3$$value3";
var pattern = @"(.*?)\$\$(.*?)(?:\^|$)";
var hash = new Dictionary<string, string>();
var match = Regex.Match(input, pattern);

while (match.Success)
{
hash.Add(match.Groups[1].Value, match.Groups[2].Value);
match = match.NextMatch();
}

Add separator to string at every N characters?

Regex.Replace(myString, ".{8}", "$0,");

If you want an array of eight-character strings, then the following is probably easier:

Regex.Split(myString, "(?<=^(.{8})+)");

which will split the string only at points where a multiple of eight characters precede it.

Extract the hash value substring from each line in a TextBox

I've done quite a bit of work to reduce your code down to the bare essentials of computing your hashes without relying on the UI. I've then got the code that requires the UI separated out so that it has nothing to do with computing hashes.

To start with I created a single hashing function that you can use to compute any hash.

public Task<string> ComputeHash(string file, Func<HashAlgorithm> create)
{
return Task.Run(() =>
{
using (var crypto = create())
{
using (var stream = File.OpenRead(file))
{
return String.Concat(
crypto.ComputeHash(stream).Select(x => x.ToString("X2")));
}
}
});
}

I've now created two fields to store the list of files and the resulting hashes.

private string[] _fileNames = null;
private string[] _hashes = null;

I'll show the code that sets the _fileNames array later, but for now this is the code that you can call to compute your hashes:

private async Task<String> Run(bool md5, bool sha1, bool sha256, bool sha512)
{
File.Delete(Path.Combine(Environment.CurrentDirectory, "log.txt"));

Func<HashAlgorithm> hashAlgorithm = null;
if (md5) hashAlgorithm = () => MD5.Create();
else if (sha1) hashAlgorithm = () => SHA1.Create();
else if (sha256) hashAlgorithm = () => SHA256.Create();
else if (sha512) hashAlgorithm = () => SHA512.Create();

if (hashAlgorithm == null)
{
return "No hash algorithm selected.";
}
else if (_fileNames == null || _fileNames.Length == 0)
{
return "No file selected." + "\n";
}
else if (_fileNames.Any(f => !File.Exists(f)))
{
return "Invalid filename." + "\n";
}
else
{
var tasks = _fileNames.Select(f => ComputeHash(f, hashAlgorithm)).ToArray();
_hashes = await Task.WhenAll(tasks);
return "Success";
}
}

The hardest part of this code, in my opinion, is the use of Func<HashAlgorithm> hashAlgorithm to store the hashing algorithm. If you're not familiar with a Func<> then it's worth looking up, but think of it as a way to store a function in a variable so that you can call the function later.

Now, finally, we have the two bits of code that interact with the UI:

private void filePickerButton_Click(object sender, RoutedEventArgs e)
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = false;
dialog.Multiselect = true;

if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
_fileNames = dialog.FileNames.ToArray();
filePicketTextBox.Text = string.Join("\n", dialog.FileNames);
}
else
{
outputTextBox.Text = "Operation cancelled." + "\n";
}
}

private async void runButton_Click(object sender, RoutedEventArgs e)
{
string result = await Run(
md5CheckBox.IsChecked,
sha1CheckBox.IsChecked,
sha256CheckBox.IsChecked,
sha512CheckBox.IsChecked);

outputTextBox.Text = result;
}

The end result is that you have two arrays, _fileNames & _hashes that you can use to get the hash for each file name. No need for splitting text.



Related Topics



Leave a reply



Submit