|
|
Hey all,
I am a bit disappointed by myself to come up with that question, but hey! there are some regex cracks here that can easily answer this question and maybe deepen my understanding. I really tried to figure out the best regex for my problem - but I am new to programming and regex' still seem to make my head explode.
Here's the string I've got:
Directory\Subdirectory\Subdir\Subsubdir\sub_sub_subv009\filename_with_lots_of_ABC123.txt
using this regex:
(?<=_)[a-zA-z0-9]*(?=.txt$)
I get:
of_ABC123
Close call, but what I need is just ABC123 - this are all characters as a string between the LAST '_' and ".txt"
Additionally, I did this in Expresso (did not use the designer but did a lot of test runs to see if my regex matches) - will this be the regex to be used in C#?
I really appreciate any hint to solve my last problem,
Best
Dennis
|
|
|
|
|
First of all, if you have a regex question, there is a regular expression forum that should be used. Secondly, not every string manipulation requires a regex - a much simpler way would be to use string.LastIndexOf for the _ and IndexOf the . character and then just extract the substring from it.
|
|
|
|
|
Here is an example of solution using both Regex and string class methods. In Regex I use a group with "FileCode" name to get result.
As Pete said not all cases require using of Regex. And in this case I think would be better to use string methods (alternative variant).
const string pattern = @"_(?<FileCode>([^_][a-zA-Z0-9])+)\.txt$";
const string text = @"Directory\Subdirectory\Subdir\Subsubdir\sub_sub_subv009\filename_with_lots_of_ABC123.txt";
var groupFileCode = Regex.Match(text, pattern);
Console.WriteLine(groupFileCode.Groups["FileCode"].Value);
int lastUnderscoreIndex = text.LastIndexOf('_');
int lastPointIndex = text.LastIndexOf('.');
Console.WriteLine(text.Substring(lastUnderscoreIndex + 1, lastPointIndex - lastUnderscoreIndex - 1));
Regards, savbace
|
|
|
|
|
Your range is [a-zA-z0-9] - notice the second "z" is lower case, and as "_" falls between uppercase A and lowercase z it is included in your match.
|
|
|
|
|
Thank you so much! I have overseen this. So I have at last understood a little bit of regex and did it right. Thank you also for the other answers, especially the C# code examples. I will try them tomorrow!
|
|
|
|
|
for reference, my regex links:
learn:
http://www.guistuff.com/articles/regexp_full_1.html
http://net.tutsplus.com/tutorials/javascript-ajax/you-dont-know-anything-about-regular-expressions/
online testing:
http://refiddle.com/
http://www.gethifi.com/tools/regex
http://gskinner.com/RegExr/
|
|
|
|
|
I'd likely use System.IO.Path.GetFileNameWithoutExtension to narrow it down first, then use LastIndexOf and Substring as others have suggested.
Were I to use a Regex, I'd likely use _(?'Name'[^_\.]+)\.
I prefer to use named groups to capture what I want.
You may want to look at the RightToLeft option as well; very handy for getting stuff that follows other stuff.
Oh, and I use this handy tool: RegexTester[^]
|
|
|
|
|
Hi,
I am in the process of writing a c# application.
There is one stored proc(sql server 2005), which is supposed to return two output values, and a resultset selection from one table.
I am able to select out the output values from stored proc(by defining the parameters with output direction), how can I select out the resultset from that one table?
Or should I write this as another stored proc?
|
|
|
|
|
Forgive me, but I'm making a few assumptions here in regards to your question...
CREATE PROCEDURE dbo.Foo
@StateCode AS CHAR(2),
@OutVariable1 AS INT OUTPUT,
@OutVariable2 AS INT OUTPUT
AS
BEGIN
SET @OutVariable1 = 100
SET @OutVariable2 = 150
SELECT * FROM dbo.Persons WHERE State = @StateCode
END
string stateCode = "AL";
int outValue1 = 0;
int outValue2 = 0;
using (SqlConnection = new SqlConnection(connectionString)) {
using (SqlCommand cmd = new SqlCommand("dbo.Foo") ) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Paramaters.Add("@StateCode", SqlDbType.Char, 2) = stateCode;
SqlParameter outValue1Param = cmd.Parameters.Add("@OutVariable1", SqlDbType.Int);
SqlParameter outValue2Param = cmd.Parameters.Add("@OutVariable2", SqlDbType.Int);
using (DataReader dr = cmd.ExecuteReader()) {
while ( dr.Read() ) {
}
}
outValue1 = (int) outValue1Param.Value;
outValue2 = (int) outValue2Param.Value;
}
}
I hope that helps.
|
|
|
|
|
Thanks so much! that looks good.
I am getting data for the while loop but in case of the output parameters, it keeps coming back with error - object reference is not set to an instance of an object. When I try to debug the program, these values are being set as null.
the stored proc does return values.
|
|
|
|
|
Hi,
I appears when I use ExecuteNonQuery to get the output parameter values, it works.
But when I use ExecuteReader, then it has NULL values for the parameters.
any thoughts?
|
|
|
|
|
Read the values from the output parameter after you've finished iterating over the reader.
|
|
|
|
|
This stored proc returns 34 values. The first 20 are required, but to maintain the file format that is being created, we are using all 34 fields. When I define the ExecuteReader, and use this form of syntax, sqlRead.GetString(25), the process fails as it is null. I would have to error check every single remaining field for nulls.
if(!sqlRead.IsDBNull(25))
{
}<br />
<br />
Is there another way to do this? Tried looking into a foreach loop, but that would not work.<br />
<br />
Thank you!!!
|
|
|
|
|
Continue to use the ExecuteReader() ...
To get the output values, you need to have first read from the DataReader and then closed it. In the case of the sample, you must have the read after the "using statement" (the using statement will automatically close the data reader), or you must force the DataReader closed before proceeding...
OPTION 1:
using ( SqlDataReader dr = cmd.executeReader() ) {
while ( dr.Read() ) {
}
}
int ouputValue = (int) outParam.Value;
OPTION 2:
SqlDataReader dr = cmd.ExecuteReader();
while ( dr.Read() ) {
}
dr.Close();
int ouputValue = (int) outParam.Value;
Does that help?
|
|
|
|
|
Thank you!! Thank you!!
Closing the reader did the trick!!!!
|
|
|
|
|
Suppose that I have a solution with many console projects, let's say P1, P2, P3. You can run each of them individually. Moreover I have a project named MENU (StartUp project), running it I'm able to call each projects of my solution (so P1, P2,P3). Each project is a console project with many static methods (so for project P1 I have P1M1, P1M2,...). Each project has an entry point Main(). Running each single project (for example P1) individually, I show a menu where I can run separately each methods of the project class (for example P1M1, P1M2,..).
The user can use the solution in two ways:
1)
Select a single project (set as StartUp), run it, for example P1. The Main() will start a menu where the user can chose a method( P1M1,P1M2,..)
2)
Run the MENU project, which call a project, then select a method.
How can I call a method P1M1 of project P1 from project MENU:
I used in the MENU project:
ProcessStartInfo start = new ProcessStartInfo();
start.FileName("P1.exe")
Process p = new Process();
p.StartInfo = start;
p.Start();
P.WaitForExit();
But in this way it call the Main(), but I want to call the method P1M1 in the P1 class.
A working solution is to make the Main of P1 with args (Main(string[] args)) and using a switch inside calling each method, but I wonder if is there a smarter solution?
|
|
|
|
|
Yes, you could allow each app to take an optional parameter to execute a particular method then exit -- and that may be a good idea. Using a switch is OK, but may be more maintenance than you want.
Additionally, you could have the MENU app have references to the other apps and call their methods directly rather than using a Process. You could even use the other apps as plug-ins if you want.
Granted, this kind of thinking leads to a fairly complex framework with its own maintenance issues, so you need to use your own judgement about how you predict the system will grow in the future.
|
|
|
|
|
I would just recommend MEF for the plug-in architecture, but I know how you like to re-invent everything .
|
|
|
|
|
|
I can solve using reflection:
I instantiate an Assembly aP1 the assembly P1, then I can easily call methods...
It is a good idea?
|
|
|
|
|
|
|
No, it's hacked up work around for a bad design.
What you should have done is put all the functionality you wanted to call into a class library. Then you can call that functionality from either the console applications OR from your menu driven application. The menu app would use the class library directly and not bother with teh console apps at all.
|
|
|
|
|
Oky, but in this way each project can not also used as stand alone Console Project (a functionality that I need)
|
|
|
|