A Better Way?

L

Luca Risolia

Am 10.03.13 01:48, schrieb Luca Risolia:
On 08/03/2013 22:21, Mike Copeland wrote:
Is there a better way (less code, less convoluted, etc.) to
access
the last character of a string variable than this?:

if(str2.at(str2.length()-1) != '/') str2 +="/";

str2 = std::regex_replace(str2, std::regex("[^/]$|^$"), "$&/");

Is this an attempt to come up with the most convoluted and least
efficient solution to the problem as you can?

It's a great benefit to get familiar with regular expressions (which are
not specific to C++ only) and profit by std::regex to solve those kind
of problems with strings, starting from simple cases like the above. By
looking at the code given by the OP and considering what "/" separators
could be for, I don't think efficiency is the main concern there, nor
the OP talked about efficiency explicitly.

I agree regexes are strong tools and love to see them in the standard
library. However, Juha is right that the regex you give is quite
advanced and hard to understand.
An approach more similar to the OPs
program looks like this:

str2 = std::regex_replace(str2, std::regex("/?$"), "/");

This RE matches the empty string at the end, when no / is present.

No, sorry, that cannot be "more similar" to what the OP asked (except
when the string is empty, as you said), because it adds an unwanted "/"
when str2 has a final "/".
 
L

Luca Risolia

if(str2.at(str2.length()-1) != '/') str2 +="/";

str2 = std::regex_replace(str2, std::regex("[^/]$|^$"), "$&/");

Is this an attempt to come up with the most convoluted and least
efficient solution to the problem as you can?

It's a great benefit to get familiar with regular expressions (which are
not specific to C++ only) and profit by std::regex to solve those kind
of problems with strings, starting from simple cases like the above. By
looking at the code given by the OP and considering what "/" separators
could be for, I don't think efficiency is the main concern there, nor
the OP talked about efficiency explicitly.

But if you're going to learn to use regexps, you should at least learn to
use them correctly. In particular, you shouldn't construct multiple
temporary regexp objects from a given string literal, as constructing a
regexp can be expensive.

Ok...BUT I did not construct *multiple* temporaries :) There's *one*
temporary in the answer I gave to the OP. Again, simple question, simple
answer, that's all.
 
N

Nobody

Ok...BUT I did not construct *multiple* temporaries :) There's *one*
temporary in the answer I gave to the OP.

Ah, but how many times does that code get executed?

Ultimately, your example isn't really any worse than those on
cplusplus.com or cppreference.com, both of which create instances of
std::regex as automatic variables within main().

But in "real" code, a given regexp is often matched against more than one
string. In that situation, not compiling the regexp each time is quite
important.
 
L

Luca Risolia

Am 10.03.13 14:11, schrieb Luca Risolia:

Have you tried it?
Yes.

Apparently I can't get it to work at all with my
compiler:( I have only tried with a different tool (Tcl), and there it
does what the OP wanted, as far as I understood the request:
(Tests) 51 % regsub "/?$" "test/" "/"
test/

Try your code with boost::regex with the ECMAScript grammar enabled,
which is the default in the standard: "test/" will be modified in "test//".
 
L

Luca Risolia

Ah, but how many times does that code get executed?

Only the OP knows how many times the code get executed in the program.
She might well notice that the compiler is able to move the
invariant constructor outside a loop, for example, and prefer to stay
with the one-line solution.
Ultimately, your example isn't really any worse than those on
cplusplus.com or cppreference.com, both of which create instances of
std::regex as automatic variables within main().

...because they are examples aimed to showing what regex's are? Anyway,
that's off-topic.
But in "real" code, a given regexp is often matched against more than
one string. In that situation, not compiling the regexp each time is
quite important.

Not relevant to the question, sorry.
 
L

Luca Risolia

I thought regexes always matched the largest possible string, rather
than the shortest possible.

EMCAScript supports non-greedy matches.
In other words, if your regex would be like "<.*>" and the input string
is like "<p>hello</p>" then it would match the entire string (rather
than just the "<p>" at the beginning.)

The correct regex in EMCAScript is "<.*>.*</.*>". To see how non-greedy
Likewise "/?$" would match the largest possible string, so in "test/"
it would match the "/" at the end.

If it instead matches the shortest possible string, I think that would
break things badly (eg. suddenly ".*" would start to always matching a
zero-length substring.)

If I am not wrong ".*" should match one empty (sub)string and the
non-empty string (two matches). Anyway, "everything" becomes "(.|\n)*"
in EMCAScript (note "\n", as the "." does not match a newline)
 
Ö

Öö Tiib

Am 10.03.13 14:11, schrieb Luca Risolia:

Have you tried it? Apparently I can't get it to work at all with my
compiler:( I have only tried with a different tool (Tcl), and there it
does what the OP wanted, as far as I understood the request:

(Tests) 50 % regsub "/?$" "test" "/"
test/
(Tests) 51 % regsub "/?$" "test/" "/"
test/
(Tests) 52 % regsub "/?$" "" "/"
/

Btw ... we concentrate on empty string (that is uncertain how should
behave). OP's code was defective and description vague. The situation
is unclear. He was possibly asking for something else. Hard to tell.

For example similar questions arise when someone wants to extend
directory path with slash for further appending a file name.
If empty string means "current directory" (not "root directory")
then adding slash to it might result with wrong outcome.
 
S

Stefan Ram

Luca Risolia said:
Only the OP knows how many times the code get executed in the program.

In programming, the number of time a piece of code gets
executed can be determined as late as at runtime.

Since the OP might not be present at every execution of his
programs (think of executions in the remote future) even the
OP himself cannot know in general how many times the code
gets executed during a specific execution or even what the
average of this number of times averaged over all executions
of the program is.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top