Replace \ with \\ doesn't work for specific variable - c#

I am trying to replace a \ with \\ and it works with everything except the specific variable I need it to work on. Throwing the error Illegal characters in path. probably because it thinks \t is a character, which is tab and is therefor not allowed in a path
the variable is loaded in from a json file using Newtonsoft.Json in to a class
public class WebsiteConfig
{
public string Name { get; set; }
public string Directory { get; set; }
}
I have tried
var escapedir = Regex.Replace(Directory, #"\\", #"\"); and any possible way I could form var escapedir = Directory.Replace("\", "\\");.
Trying Regex.Replace("C:\test", #"\", #"\\"); (C:\test being the exact same as in Directory) worked perfectly and then inside a foreach I am trying to combine the Directory with a filename.
"Dump" of current code:
var json = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "config.json"));
_config = JsonConvert.DeserializeObject<Config>(json);
foreach(WebsiteConfig website in _config.WebsiteConfigList)
{
for (int i = 0; i <= 9; i++)
{
string dir = website.Directory;
string escapedir = Regex.Replace(dir, #"\\", #"\\\\");
var path = Path.Combine(escapedir, "Backedup_" + i.ToString() + ".txt");
}
}
And config.json:
{
"WebsiteConfigList": [
{
"Name": "test",
"Directory": "C:\test"
}
]
}
Here's a screenshot to show the exception:

The problem does indeed originate with \t but it happens during deserialisation and not with the Path as you might believe. There have been multiple suggestions to replace the backslash with an escaped backslash, but at that point the damage was already done:
The C:\test had become C: est (whitespace is a tab char).
As per your requirement, altering the input file is not an option, so you have to do your escaping before deserialisation. The simplest way I can think of is:
json = json.Replace(#"\", #"\\");
By the way, while Regex.Replace is quite powerfull, string.Replace is adequate.
It doesn't look like you have large JSON files, but if you do, read a bit here on string.Replace on large files.

If you can't change the source JSON to be "C:\\test" instead of "C:\test" then detect the tab and replace it with what you want
string escapedir = Regex.Replace(dir, #"\t", #"\\\\t");

Related

Process.Start(FilePath) with commas

When searching a directory for files of a specific name driven by the _fileToSearch parameter, I then create a custom list of DrawingFound and store the files path in a string called FileDirectory.
I then require on a button click OpenDrawing() for the file stored within FileDirectory to open to the user. This works in most cases, however, if the path has a , for example then the explorer defaults to opening the users documents directory. How can I handle commas within a file path to achieve the desired outcome?
public partial class DrawingFound
{
public string DrawingName;
public string FileType;
public string FileDirectory;
public string Revision;
public void OpenDrawing()
{
Process.Start("Explorer.exe", FileDirectory);
}
}
public void GetDrawings()
{
string _searchFolder = #"C:\Users\ThisUser\Documents";
string _fileToSearch = "Example of file, where a comma is used.txt";
ObservableCollection<DrawingFound> _drawings = new();
DirectoryInfo dirInfo = new(_searchFolder);
FileInfo[] files = dirInfo.GetFiles($"*{_fileToSearch}*", SearchOption.AllDirectories);
foreach (FileInfo file in files)
{
if (!_drawings.Any(item => $"{item.DrawingName}{item.FileType}" == file.Name))
{
_drawings.Add(new DrawingFound
{
DrawingName = Path.GetFileNameWithoutExtension(file.Name),
FileType = file.Extension,
FileDirectory = file.FullName,
Revision = "- Ignore -"
});
}
}
}
depending on your OS, you may need to use "escaping"
For example, to store a string one "two" three in a literal delimited with quotation marks, you need to escape the quotation marks. Depending on the language and environment, the "escape character" can be e.g. a \
in this example:
foo = "one \"two\" three"
I hope this helps; otherwise, please be more specific about your language, OS, e.t.c.
Thank you to everyone for your assistance with this matter. I managed to fix the issue and the operation now works as expected. #George Rey following your example I added the escape characters to achieve this:
Process.Start("explorer.exe", $"\"{FileDirectory}\"");
After you did your edits, the problem is more clear:
I guess that your OS is windows.
The problem is not with the comma but rather with the space.
The system treats the characters before the space as "file path" and the rest as "parameters." This is for historical reasons.
wrap the entire path in "embedded quotes" so that it is clear to the OS that the entire string is a path. This should prevent it from trying to elide the command parameters out of that string

Find comments in text and replace them using Regex

I currently go trought all my source files and read their text with File.ReadAllLines and i want to filter all comments with one regex. Basically all comment possiblities. I tried several regex solutions i found on the internet. As this one:
#"(#(?:""[^""]*"")+|""(?:[^""\n\\]+|\\.)*""|'(?:[^'\n\\]+|\\.)*')|//.*|/\*(?s:.*?)\*/"
And the top result when i google:
string blockComments = #"/\*(.*?)\*/";
string lineComments = #"//(.*?)\r?\n";
string strings = #"""((\\[^\n]|[^""\n])*)""";
string verbatimStrings = #"#(""[^""]*"")+";
See: Regex to strip line comments from C#
The second solution won't recognize any comments.
Thats what i currently do
public static List<string> FormatList(List<string> unformattedList, string dataType)
{
List<string> formattedList = unformattedList;
string blockComments = #"/\*(.*?)\*/";
string lineComments = #"//(.*?)\r?\n";
string strings = #"""((\\[^\n]|[^""\n])*)""";
string verbatimStrings = #"#(""[^""]*"")+";
string regexCS = blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings;
//regexCS = #"(#(?:""[^""]*"")+|""(?:[^""\n\\]+|\\.)*""|'(?:[^'\n\\]+|\\.)*')|//.*|/\*(?s:.*?)\*/";
string regexSQL = "";
if (dataType.Equals("cs"))
{
for(int i = 0; i < formattedList.Count;i++)
{
string line = formattedList[i];
line = line.Trim(' ');
if(Regex.IsMatch(line, regexCS))
{
line = "";
}
formattedList[i] = line;
}
}
else if(dataType.Equals("sql"))
{
}
else
{
throw new Exception("Unknown DataType");
}
return formattedList;
}
The first Method recognizes the comments, but also finds things like
string[] bla = text.Split('\\\\');
Is there any solution to this problem? That the regex excludes the matches which are in a string/char? If you have any other links i should check out please let me know!
I tried a lot and can't figure out why this won't work for me.
[I also tried these links]
https://blog.ostermiller.org/find-comment
https://codereview.stackexchange.com/questions/167582/regular-expression-to-remove-comments
Regex to find comment in c# source file
Doing this with regexes will be very difficult, as stated in the comments. However, a fine way to eliminate comments would be by utilizing a CSharpSyntaxWalker. The syntaxwalker knows about all language constructs and won't make hard to investigate mistakes (as regexes do).
Add a reference to the Microsoft.CodeAnalysis.CSharp Nuget package and inherit from CSharpSyntaxWalker.
class CommentWalker : CSharpSyntaxWalker
{
public CommentWalker(SyntaxWalkerDepth depth = SyntaxWalkerDepth.Node) : base(depth)
{
}
public override void VisitTrivia(SyntaxTrivia trivia)
{
if (trivia.IsKind(SyntaxKind.MultiLineCommentTrivia)
|| trivia.IsKind(SyntaxKind.SingleLineCommentTrivia))
{
// Do something with the comments
// For example, find the comment location in the file, so you can replace it later.
// Make a List as a public property, so you can iterate the list of comments later on.
}
}
}
Then you can use it like so:
// Get the program text from your .cs file
SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
var walker = new CommentWalker();
walker.Visit(root);
// Now iterate your list of comments (probably backwards) and remove them.
Further reading:
Syntax walkers
Checking for big blocks of comments in code (NDepend, Roslyn)

How can i remove the part "http://" from a string?

I have this method:
private List<string> offline(string targetDirectory)
{
if (targetDirectory.Contains("http://"))
{
MessageBox.Show("true");
}
DirectoryInfo di = new DirectoryInfo(targetDirectory);
List<string> directories = new List<string>();
try
{
string[] dirs = Directory.GetDirectories(targetDirectory,"*.*",SearchOption.TopDirectoryOnly);
for (int i = 0; i < dirs.Length; i++)
{
string t = "http://" + dirs[i];
directories.Add(t);
}
}
catch
{
MessageBox.Show("hgjghj");
}
return directories;
}
This is the part:
if (targetDirectory.Contains("http://"))
{
MessageBox.Show("true");
}
I'm getting a directory which give me all the directories in this directory and I'm adding to each directory the string "http://".
The problem is when next time a directory is getting to the function its coming with "http://"
For example: http://c:\\ or http://c:\\windows
And then the line
DirectoryInfo di = new DirectoryInfo(targetDirectory); // throws exception.
So I want that each time a directory is getting to the function to check if it starts with "http://" in the beginning, strip the "http://" part, get all the directories, and then add to each directory "http://" like now.
How can I remove "http://"?
I would be stricter than using Contains - I'd use StartsWith, and then Substring:
if (targetDirectory.StartsWith("http://"))
{
targetDirectory = targetDirectory.Substring("http://".Length);
}
Or wrap it in a helper method:
public static string StripPrefix(string text, string prefix)
{
return text.StartsWith(prefix) ? text.Substring(prefix.Length) : text;
}
It's not clear to me why you're putting the http:// as a prefix anyway though, to be honest. I can't see how you'd expect a directory name prefixed with http:// to be a valid URL. Perhaps if you could explain why you're doing it, we could suggest a better approach.
(Also, I really hope you don't have a try/catch block like that in your real code, and that normally you follow .NET naming conventions.)
The problem is how can i remove the http:// ?
You may use string.Replace, and replace the string with an empty string.
targetDirectory = targetDirectory.Replace("http://","");
or
targetDirectory = targetDirectory.Replace("http://",string.Empty);
both of them are same
Try this:
if(example.StartsWith("http://"))
{
example.substring(7);
}
You can always use the String.Replace to remove / replace characters in the string.
Exampel:
targetDirectory = targetDirectory.Replace("http://", string.Empty);
And you can check if the string begins with Http:// by doing
if(targetDirectory.StartsWith("http://"))
You can use the replace characters in the string by string.Replace
if (targetDirectory.Contains("http://"))
{
targetDirectory = targetDirectory.Replace("http://",string.Empty);
}

c# Rich text Format error in code

hoping you can help
I have the following code
List<string> comconfig = populate.resolveconfig(_varibledic, populate.GetVaribles[0].Substring(populate.GetVaribles[0].IndexOf("=") + 1)); //get the aray of strings
string config = ""; //create a empty otput string
config = #"\rtf1\ansi\deff0\deftab240 {\fonttbl {\f000 Monaco;} {\f001 Monaco;} } {\colortbl \red255\green255\blue255; \red000\green000\blue000; \red255\green255\blue255; \red000\green000\blue000; }";
config = config + #"\f96\fs20\cb3\cf2 \highlight1\cf0 "; // assigned rtf header to output string
foreach (var strings in comconfig) //loop though array adding to output string
{
config = config + strings + #"\par ";
}
config = config + "}"; //close of RTF code
So trying to create a RTF string that I can later display. comconfig is an array of strings with some RTF mark up for highlighting and stuff.
trouble is that if I use # then I get double \ which mess up the RTF, and if i dont use them, then the escape charatures mess up the code??
what is the best way to build up this string by adding a preformated RTF header and the aray of strings in the middle. it is displayed finaly in a RTF.textbox. or converted to a plain text string at the users request. I need to ignore the escape charatures with out messing up the RTF?
Cheers
Aaron
No, you don't get a double \. You're getting confuzzled by the debugger display of the string. It shows you what the string looks like if you had written it in C# without the #. Click the spy glass icon at the far right and select the Text Visualizer.

Path functions for URL

I want to use functions of Path class (GetDirectoryName, GetFileName, Combine,etc.) with paths in URL format with slash (/).
Example of my path:
"xxx://server/folder1/folder2/file"
I tried to do the job with Path functions and in the end just replaced the separator.
I've found that the GetDirectoryName function does not correctly replace the slashes:
Path.GetDirectoryName(#"xxx://server/folder/file") -> #"xxx:\server\folder"
Like you see one slash is lost.
How can I cause the Path functions to use the 'alternative' separator?
Can I use another class with the same functionality?
I'm afraid GetDirectoryName, GetFileName, Combine,etc. use Path.DirectorySeparatorChar in the definition and you want Path.AltDirectorySeparatorChar.
And since Path is a sealed class, I think the only way to go about is string replacement.You can replace Path.DirectorySeparatorChar('\') with Path.AltDirectorySeparatorChar('/') and Path.VolumeSeparatorChar(':') with ":/"
For GetDirectoryName(), you can use
pageRoot = uri.Remove(uri.LastIndexOf('/') + 1);
Have you considered using a combination of System.Uri, System.UriBuilder, and (if necessary) custom System.UriParser subclass(es)?
If the URI is a local file URI of the form file://whatever then you can call string path = new Uri(whatever).LocalPath and call the Path methods on it. If you cannot guarantee the Uri is to a local path, you cannot guarantee components of the Uri correspond to machines, folders, files, extensions, use directories, separator characters, or anything else.
Long time after...I was looking for a solution and found this topic, so i decided to make my (very simple) code
string dirRootUpdate = string.Empty;
string fileNameupdate = string.Empty;
string pathToGetUpdate = string.Empty;
string[] _f = Properties.Settings.Default.AutoUpdateServerUrl.Split('/');
for (int i = 0; i < _f.Count() - 1; i++)
{
dirRootUpdate += _f[i];
if (i == 0) // is the first one
{
dirRootUpdate += "/";
}
else if (i != _f.Count() - 2) // not the last one ?
{
dirRootUpdate += "/";
}
}
fileNameupdate = _f[_f.Count() - 1];
the setting "Properties.Settings.Default.AutoUpdateServerUrl" contains the string to be verified
Works fine, may require some refination to look better.
Hope could help someone

Categories