I have written a small class that works in extracting Snapchat usernames from common conventions of sentences, manipulating the positioning of certain characters to hopefully extract a valid username.
The script does have some partial protection for validity with its call to SnapchatUtilities.IsUsernameWellFormatted(extractedFromConvention)
, but other than that its treated as a magick library with no assured accuracy, returns null if extraction fails.
Its written to try and keep things simple, rather than repeating the same thing over and over, I try and create a list of the conventions, then loop the logic for checking via TryExtractUsernameFromConvention
Examples
- Library will convert a string like "Isn't it a lovely day today? 👻:username1here lets go for a walk" to "username1here"
- Library will convert a string like "Some random person walked into my house today. sc ; addthisusername93 - Isn't this area rather populated?" to "addthisusername93"
Class:
public class SnapchatUsernameExtractor
{
private static readonly List<string> Conventions = new()
{
// "sc"
"sc.", "sc:", "sc :", "sc-", "sc -", "sc~", "sc ~", "sc;", "sc ;", "sc👻", "sc 👻", "sc•", "sc •", "sc//", "sc //", "sc/", "sc|",
// "snap"
"snap:", "snap :", "snap-", "snap -", "snap~", "snap ~", "snap;", "snap ;", "snap•", "snap •","snap👻", "snap 👻", "snap/", "snap//",
// "scm"
"scm:", "scm :", "scm-", "scm -", "scm~", "scm ~", "scm;", "scm ;", "scm👻", "scm 👻", "scm•", "scm •",
// "snapchat"
"snapchat;", "snapchat~", "snapchat-", "snapchat -", "snapchat👻:", "snapchat👻~", "snapchat👻", "snapchat•", "snapchat •",
"snapchat//", "snapchat |", "snapchat:", "snapchat-",
// unsorted
"snap me~", "👻:", "👻-", "👻~", "👻;", "👻•", "𝕊𝕟𝕒𝕡-", "👻 -", "snap me", "👻 ", "snapchatt~"
};
public static string? TryGetUsernameFromString(string s)
{
foreach (var convention in Conventions.Where(s.Contains))
{
var extractedFromConvention = TryExtractUsernameFromConvention(convention, s);
if (!string.IsNullOrEmpty(extractedFromConvention) && SnapchatUtilities.IsUsernameWellFormatted(extractedFromConvention))
{
return extractedFromConvention;
}
}
return null;
}
private static string? TryExtractUsernameFromConvention(string convention, string str)
{
if (str.Contains(convention + " "))
{
return str.Substring(str.IndexOf(convention) + convention.Length + 1).Split(" ")[0];
}
if (str.StartsWith(convention) && !str.Contains(" "))
{
return str.Substring(convention.Length);
}
if (str.Contains(convention))
{
return str.Substring(str.IndexOf(convention) + convention.Length).Split(" ")[0];
}
return null;
}
}
SnapchatUtilities:
public static class SnapchatUtilities
{
public static bool IsUsernameWellFormatted(string username)
{
if (username.Length is < 3 or > 15)
{
return false;
}
var allowedCharacters = "abcdefghijklmnopqrstuvwxyz-_.0123456789".ToCharArray();
if (username.ToCharArray().Any(x => !allowedCharacters.Contains(x)))
{
return false;
}
if ("0123456789-_.".ToCharArray().Contains(username[0]))
{
return false;
}
if ("-_.".ToCharArray().Contains(username[username.Length - 1]))
{
return false;
}
return true;
}
}
Conventions
list looks to have a few shared formats. Separating these out into the root phrases (e.g.sc
/snap
/scm
) and the possible extensions (.
,:
,~
etc) may make it easier to add new phrases/extensions if this is something you may need to do \$\endgroup\$