Odpowiedzi:
Moim zdaniem najprostsza metoda byłaby następująca:
var match = str.IndexOfAny(new char[] { '*', '&', '#' }) != -1
Lub w możliwie łatwiejszej do odczytania formie:
var match = str.IndexOfAny("*&#".ToCharArray()) != -1
W zależności od kontekstu i wymaganej wydajności możesz lub nie chcesz buforować tablicy char.
Jak powiedzieli inni, użyj IndexOfAny. Jednak użyłbym tego w ten sposób:
private static readonly char[] Punctuation = "*&#...".ToCharArray();
public static bool ContainsPunctuation(string text)
{
return text.IndexOfAny(Punctuation) >= 0;
}
W ten sposób nie tworzysz nowej tablicy przy każdym wywołaniu. Ciąg jest również łatwiejszy do zeskanowania niż seria literałów znakowych, IMO.
Oczywiście, jeśli zamierzasz użyć tego tylko raz, więc zmarnowana kreacja nie stanowi problemu, możesz użyć:
private const string Punctuation = "*&#...";
public static bool ContainsPunctuation(string text)
{
return text.IndexOfAny(Punctuation.ToCharArray()) >= 0;
}
lub
public static bool ContainsPunctuation(string text)
{
return text.IndexOfAny("*&#...".ToCharArray()) >= 0;
}
To naprawdę zależy od tego, co uznasz za bardziej czytelne, czy chcesz użyć znaków interpunkcyjnych w innym miejscu i jak często będzie wywoływana metoda.
EDYCJA: Oto alternatywa dla metody Reeda Copseya do sprawdzania, czy ciąg zawiera dokładnie jeden ze znaków.
private static readonly HashSet<char> Punctuation = new HashSet<char>("*&#...");
public static bool ContainsOnePunctuationMark(string text)
{
bool seenOne = false;
foreach (char c in text)
{
// TODO: Experiment to see whether HashSet is really faster than
// Array.Contains. If all the punctuation is ASCII, there are other
// alternatives...
if (Punctuation.Contains(c))
{
if (seenOne)
{
return false; // This is the second punctuation character
}
seenOne = true;
}
}
return seenOne;
}
ToCharArrayrazie potrzeby można użyć formularza „inline”.
Jeśli chcesz tylko sprawdzić, czy zawiera jakiś znak, polecam użycie string.IndexOfAny, jak zasugerowano w innym miejscu.
Jeśli chcesz sprawdzić, czy ciąg zawiera dokładnie jeden z dziesięciu znaków i tylko jeden, sprawa staje się nieco bardziej skomplikowana. Uważam, że najszybszym sposobem byłoby sprawdzenie skrzyżowania, a następnie sprawdzenie duplikatów.
private static char[] characters = new char [] { '*','&',... };
public static bool ContainsOneCharacter(string text)
{
var intersection = text.Intersect(characters).ToList();
if( intersection.Count != 1)
return false; // Make sure there is only one character in the text
// Get a count of all of the one found character
if (1 == text.Count(t => t == intersection[0]) )
return true;
return false;
}
String.IndexOfAny(Char[])
Dzięki Wam wszystkim! (I głównie Jon!): To pozwoliło mi napisać to:
private static readonly char[] Punctuation = "$€£".ToCharArray();
public static bool IsPrice(this string text)
{
return text.IndexOfAny(Punctuation) >= 0;
}
ponieważ szukałem dobrego sposobu na wykrycie, czy dany ciąg jest w rzeczywistości ceną lub zdaniem, na przykład „Za nisko, by wyświetlić”.