1
$\begingroup$

For example,

string = "ads, 32, dv, \"sdf\"
  sd, 213, as, \"asd
  asd\"
  asd, 123 sd, \"asd\"";

There are 3 line returns \n. I want to find the second one since it is inside the quotes ("").

StringCases[string,RegularExpression["put regular expression here"]];

I have tried the following regex which should work if only Mathematica would allow variable length lookbehind assertions:

RegularExpression["(?<=,\"[^\"]*)\\n(?=[^\"]*\",)"]
$\endgroup$
3
  • $\begingroup$ routes = quotes? Can you give Mathematica code to create the string you're actually providing in the question? Without that, it's ambiguous. $\endgroup$
    – Jens
    Jul 1, 2017 at 16:23
  • $\begingroup$ i have updated the code. $\endgroup$
    – user13892
    Jul 1, 2017 at 16:35
  • $\begingroup$ Sorry, I just saw now that i misspelled the word quote in the title. $\endgroup$
    – user13892
    Jul 1, 2017 at 19:38

2 Answers 2

3
$\begingroup$

You are able to reference the parenthesised sections of your RegularExpression on the right-hand side with RuleDelayed.

With

string = "ads, 32, dv, \"sdf\"
  sd, 213, as, \"asd
  asd\"
  asd, 123 sd, \"asd\"";

Then

StringCases[
 string,
 RegularExpression["\"([^\"]+?\n[^\"]+?)\""] :> "$1"
 ]
{"asd
asd"}

Hope this helps.

$\endgroup$
5
  • $\begingroup$ A false match is found in the string "1,\"abc\",3\n4,\"def\",6\n". $\endgroup$
    – WReach
    Jul 2, 2017 at 4:53
  • $\begingroup$ @WReach It returns {",3\n4,"} as expected (with Mathematica 8.0.4). $\endgroup$ Jul 2, 2017 at 9:46
  • $\begingroup$ @Edmund Actually Rule works here as well as RuleDelayed. $\endgroup$ Jul 2, 2017 at 9:46
  • 1
    $\begingroup$ @AlexeyPopkov I was assuming that the usual rules for matching quotes were to be respected (e.g. like in CSV parsing). Under that assumption, I expect no matches from my example. Perhaps the OP can clarify whether quote matching is a requirement. $\endgroup$
    – WReach
    Jul 2, 2017 at 14:08
  • $\begingroup$ @WReach Thanks, added a special note to my answer. $\endgroup$ Jul 2, 2017 at 14:22
1
$\begingroup$

Here is a solution which won't include the outer quotes in the matched string and hence will count every quote twice:

StringCases["a\"b\nc\"d\ne\"", RegularExpression["(?<=\")[^\"]+?\n[^\"]+?(?=\")"]]
{"b\nc", "d\ne"} 

Compare to Edmund's solution:

StringCases["a\"b\nc\"d\ne\"", 
 RegularExpression["\"([^\"]+?\n[^\"]+?)\""] :> "$1"]
{"b\nc"}

Note that both solutions use + instead of * since you wish to find only the second \n what contradicts the title of the question: "regex to find \n within quotes and not ones outside quotes". Based on the title only, the solution would use * in order to allow matching lonely newline character inside of the quotes:

StringCases[string, RegularExpression["(?<=\")[^\"]*?\n[^\"]*?(?=\")"]]
{"\n  sd, 213, as, ", "asd\n  asd", "\n  asd, 123 sd, "} 

It is worth to add also that both mine and Edmund's solution completely ignore the usual rules for matching quotes as WReach correctly notes in the comment. If quote matching is required, one should apply approaches shown in the following threads:

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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