4
$\begingroup$

Say I have the code below to extract those lines with "::" in a string snippet:

StringCases["fdsa
fds
fdsa
ss::x
x::2",
Shortest[StartOfLine ~~ __ ~~ "::" ~~ __ ~~ EndOfLine]][[1]]

However, the first occurrence involves more lines than I want:

    fdsa
    fds
    fdsa
    ss::x

As I would assume first three lines should be excluded by using Shortest and StartOfLine, why does Mathematica give an answer like that?

$\endgroup$
  • 1
    $\begingroup$ Why ? Answer in this question where the mentionned "A" is StartOfLine in your case $\endgroup$ – andre314 Sep 29 '17 at 19:03
2
$\begingroup$

The string subpattern __ in StartOfLine ~~ __ ~~ "::" will match any characters, including line endings. That is why the first match spanned line boundaries: it was the "shortest" match starting from the first start-of-line found.

To prevent this behaviour, we must explicitly exclude line endings. For example:

StringCases["fdsa
fds
fdsa
ss::x
x::2",
Shortest[StartOfLine ~~ Except["\r"|"\n"].. ~~ "::" ~~ __ ~~ EndOfLine]][[1]]

(* "ss::x" *)

The line ending characters are specified explicitly since Except in string patterns can only be applied to single characters -- and line endings are multi-character in general across platforms.

The modifier Shortest might imply that it will find the shortest possible match, but it really only means the "shortest match starting from the initial search point". This point is elaborated further in (72283). The present question might be considered to be a duplicate of that other question, but a distinction might be drawn due to the added complication of applying Except to line endings.

$\endgroup$
1
$\begingroup$
StringCases["fdsa
 fds
 fdsa
 ss::x
 x::2", 
 Except["\n" ] .. ~~ "::" ~~ Except["\n"] ..]

{"ss::x", "x::2"}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.