8
$\begingroup$

Consider a string like:

str = "AabHHioPjggtYuggbwq";

I would like to have a function getpairs[x_String] that would extract for me:

getpairs[str]

{"Aa","HH","gg","gg"}

Any suggestions how to do this?

$\endgroup$
  • 2
    $\begingroup$ Could your input contain something like aaa? If so do you expect one or two aa in the result? (Or alternatively, if there's aAa, do you want both aA and Aa?) $\endgroup$ – Martin Ender Feb 14 '17 at 16:24
  • $\begingroup$ Good point! I did not think about 3 letters yet. I guess if 3 appear, I would like to take them out separately. So, extract all occurrences of repeated letters (two or more). In your example: ...,"aaa",...,"aAa",..., $\endgroup$ – Kagaratsch Feb 14 '17 at 16:41
17
$\begingroup$
str = "AabHHioPjggtYuggbwq";
StringCases[str, x_ ~~ x_, IgnoreCase -> True]

{"Aa", "HH", "gg", "gg"}

Or in the generalized version of the question:

str = "AaAbHHhhhioPjggtYuggGgGbwq";
StringCases[str, x_ ~~ (x_) .., IgnoreCase -> True]

{"AaA", "HHhhh", "gg", "ggGgG"}

$\endgroup$
  • 3
    $\begingroup$ After the OP's clarification in a comment on the question, I think this should be x_ ~~ x_ ... $\endgroup$ – Martin Ender Feb 14 '17 at 16:43
  • $\begingroup$ Funny. :)This deserve 10 vote(include my one.)? $\endgroup$ – yode Feb 14 '17 at 17:23
  • 1
    $\begingroup$ the generalized case needs parenthesis: x_ ~~ (x_) .. $\endgroup$ – george2079 Feb 14 '17 at 18:43
  • $\begingroup$ I'd generalize by allowing overlaps, at least that's how the question reads to me $\endgroup$ – LLlAMnYP Feb 15 '17 at 5:31
  • 2
    $\begingroup$ @george2079 Not really, the space is sufficient. However, for some reason when copying the string without parenthesis into Mathematica, it just removes the space (if you reinserted manually it works). The worst part about that is that this short snippet doesn't survive a roundtrip transform out of and back into Mathematica. Maybe this should be reported as a bug... $\endgroup$ – Martin Ender Feb 15 '17 at 13:26
5
$\begingroup$
getpairs[str_String] := StringJoin @@@ Select[
   Partition[Characters[str], 2, 1],
   SameQ @@ ToUpperCase[#] &]

str = "AabHHioPjggtYuggbwq";

getpairs[str]

(*  {"Aa", "HH", "gg", "gg"}  *)
$\endgroup$
  • $\begingroup$ Unfortunately, this doesn't generalise easily to the OP's comment on the question in the case of more than 2 consecutive occurrences of a letter. $\endgroup$ – Martin Ender Feb 14 '17 at 16:43
  • $\begingroup$ @MartinEnder Well, we can't be expected to be prescient... $\endgroup$ – C. E. Feb 15 '17 at 9:21
  • $\begingroup$ @C.E. No, but I think it's a good idea to think about edge cases the OP might be overlooking (or neglected to mention) and ask for clarification before answering. $\endgroup$ – Martin Ender Feb 15 '17 at 13:25
  • $\begingroup$ @MartinEnder The title mentions "pairs", the name of the function in the question is "getpairs". So you would have us ask, "do you mean pairs?" I don't buy it. It's better to post the answer and wait for a reaction from OP, who may choose to request improvements if he wants. Needless to say, one should not post an answer if one does not understand the question. But both Bob and I got it right, as evidenced by the fact that my answer was accepted without the general case. $\endgroup$ – C. E. Feb 15 '17 at 14:25
  • $\begingroup$ @C.E. Yes, the question says "pairs". Nevertheless, it was completely unclear what should happen to the input "aAa" (or whether the OP assumes that this case will never appear in the input). $\endgroup$ – Martin Ender Feb 15 '17 at 14:29
5
$\begingroup$

I will give a RegularExpression version here.

str = "AabHHioPjggtYuggbwq";
StringCases[str, RegularExpression["(?i)(\\w)\\1"]]

{"Aa", "HH", "gg", "gg"}


Per this comment,that the string contain 3 or more letter case

str = "aAabHhHioPjggtYuggbwwq";
StringCases[str, RegularExpression["(?i)(\\w)\\1+"]]

{"aAa", "HhH", "gg", "gg", "ww"}

$\endgroup$
  • $\begingroup$ You can use \\1+ instead of \\1*\\1 (and it would be marginally more efficient to switch that around to \\1\\1* if you kept it). Also note that \\w matches more than just letters (but not all characters either). $\endgroup$ – Martin Ender Feb 15 '17 at 13:28
  • $\begingroup$ @MartinEnder Wow,thanks for your advice. $\endgroup$ – yode Feb 15 '17 at 13:52

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.