ben
ben

Reputation:

how to parse string for capitalized words

I have this string: " Mimi loves Toto and Tata hate Mimi so Toto killed Tata"

I want to write a code that print only the words that begin with capital letters, avoiding repetition

the Output should be like

Mimi
Toto
Tata

I tried to do so but I'm sure its wrong even though no errors are showing.

The code i wrote :

static void Main(string[] args)
        {
            string s = "Memi ate Toto and she killed Tata Memi also hate Biso";
            Console.WriteLine((spliter(s)));
        }



        public static string spliter(string s)
        {

            string x = s;
            Regex exp = new Regex(@"[A-Z]");
            MatchCollection M = exp.Matches(s);

            foreach (Match t in M)
            {

                while (x != null)
                {
                    x = t.Value;  
                }

            }
            return x;
        }


    }
}

Idea:

What if i split the string into an array, then apply a regex to check them word by word and then print the results ? I don't know - can any one help me in making this code work?

Upvotes: 0

Views: 3316

Answers (12)

Kirill Polishchuk
Kirill Polishchuk

Reputation: 56162

Appropriate regex: \b\p{Lu}\p{L}*

var result = 
    Regex.Matches(input, @"\b\p{Lu}\p{L}*")
    .Cast<Match>().Select(m => m.Value);

Upvotes: 1

Sam
Sam

Reputation: 181

function capitalLetters() {
  var textAreaId = "textAreaId";
  var resultsArray = $(textAreaId).value.match( /\b[A-Z][A-Za-z']+/g );
  displayResults(textAreaId, resultsArray);
}

Upvotes: -1

Konstantin Spirin
Konstantin Spirin

Reputation: 21271

    static Regex _capitalizedWordPattern = new Regex(@"\b[A-Z][a-z]*\b", RegexOptions.Compiled | RegexOptions.Multiline);

    public static IEnumerable<string> GetDistinctOnlyCapitalizedWords(string text)
    {
        return _capitalizedWordPattern.Matches(text).Cast<Match>().Select(m => m.Value).Distinct();
    }

Upvotes: 0

Michael Buen
Michael Buen

Reputation: 39393

David B's answer is the best one, he takes into account the word stopper. One vote up.

To add something to his answer:

        Func<string,bool,string> CaptureCaps = (source,caseInsensitive) => string.Join(" ", 
                new Regex(@"\b[A-Z]\w*").Matches(source).OfType<Match>().Select(match => match.Value).Distinct(new KeisInsensitiveComparer(caseInsensitive) ).ToArray() );


        MessageBox.Show(CaptureCaps("First The The  Quick Red fox jumped oveR A Red Lazy BRown DOg", false));
        MessageBox.Show(CaptureCaps("Mimi loves Toto. Tata hate Mimi, so Toto killed TaTa. A bad one!", false));


        MessageBox.Show(CaptureCaps("First The The  Quick Red fox jumped oveR A Red Lazy BRown DOg", true));
        MessageBox.Show(CaptureCaps("Mimi loves Toto. Tata hate Mimi, so Toto killed TaTa. A bad one!", true));


class KeisInsensitiveComparer : IEqualityComparer<string>
{
    public KeisInsensitiveComparer() { }

    bool _caseInsensitive;
    public KeisInsensitiveComparer(bool caseInsensitive) { _caseInsensitive = caseInsensitive; }


    // Products are equal if their names and product numbers are equal.
    public bool Equals(string x, string y)
    {

        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;



        return _caseInsensitive ? x.ToUpper() == y.ToUpper() : x == y;
    }

    // If Equals() returns true for a pair of objects,
    // GetHashCode must return the same value for these objects.

    public int GetHashCode(string s)
    {
        // Check whether the object is null.
        if (Object.ReferenceEquals(s, null)) return 0;

        // Get the hash code for the Name field if it is not null.
        int hashS = s == null ? 0 : _caseInsensitive ? s.ToUpper().GetHashCode() : s.GetHashCode();

        // Get the hash code for the Code field.
        int hashScode = _caseInsensitive ? s.ToUpper().GetHashCode() : s.GetHashCode();

        // Calculate the hash code for the product.
        return hashS ^ hashScode;
    }

}

Upvotes: 0

GWLlosa
GWLlosa

Reputation: 24403

I'd suggest do a string.split to seperate the string into words, and then just print words where char.IsUpper(word[0]) is true.

Something like this

Upvotes: 2

Amy B
Amy B

Reputation: 110071

Since others have already posted so much of the answer, I don't feel I'm breaking any homework rules to show this:

//set up the string to be searched
string source =
"First The The Quick Red fox jumped oveR A Red Lazy BRown DOg";

//new up a Regex object.
Regex myReg = new Regex(@"(\b[A-Z]\w*)");

//Get the matches, turn then into strings, de-dupe them
IEnumerable<string> results =
    myReg.Matches(source)
    .OfType<Match>()
    .Select(m => m.Value)
    .Distinct();

//print out the strings.
foreach (string s in results)
    Console.WriteLine(s);
  • For learning the Regex type, you should start here.
  • For learning the Linq in-memory query methods, you should start here.

Upvotes: 1

ʞɔıu
ʞɔıu

Reputation: 48386

I don't know the C#/.net regex lib at all, but this this regex pattern will do it:

\b[A-Z][a-z]+

the \b means the match can only start at the beginning of a word. change + to * if you want to allow single-word capitals.

Edit: You want to match "McDonald's"?

\b[A-Z][A-Za-z']+

If you don't want to match ' if it only appears at the end of a string, then just do this:

\b[A-Z][A-Za-z']+(?<!')

Upvotes: 7

Perry Neal
Perry Neal

Reputation: 765

string foo = "Mimi loves Toto and Tata hate Mimi so Toto killed Tata";
char[] separators = {' '};
IList<string> capitalizedWords = new List<string>();
string[] words = foo.Split(separators);
foreach (string word in words)
{
    char c = char.Parse(word.Substring(0, 1));

    if (char.IsUpper(c))
    {
        capitalizedWords.Add(word);
    }
}

foreach (string s in capitalizedWords)
{
    Console.WriteLine(s);
}

Upvotes: 0

Michael Buen
Michael Buen

Reputation: 39393

C# 3

        string z = "Mimi loves Toto and Tata hate Mimi so Toto killed Tata";
        var wordsWithCapital = z.Split(' ').Where(word => char.IsUpper(word[0])).Distinct();
        MessageBox.Show( string.Join(", ", wordsWithCapital.ToArray()) );

C# 2

        Dictionary<string,int> distinctWords = new Dictionary<string,int>();
        string[] wordsWithInitCaps = z.Split(' ');
        foreach (string wordX in wordsWithInitCaps)
            if (char.IsUpper(wordX[0]))
                if (!distinctWords.ContainsKey(wordX))
                    distinctWords[wordX] = 1;
                else
                    ++distinctWords[wordX];                       


        foreach(string k in distinctWords.Keys)
            MessageBox.Show(k + ": " + distinctWords[k].ToString());

Upvotes: 5

missaghi
missaghi

Reputation: 5090

use this regex

([A-Z][a-z]+)

explanation:

[A-Z]    [a-z]+
  |        |
Single   Multiple(+)
  |        |
  C      apital   -> Capital

Try out regex here

Upvotes: 2

Brian
Brian

Reputation: 25834

Solution. Notice use of built in string splitter. You could replace the toupper stuff by checking if the first character is between 'A' and 'Z'. Removing duplicates I leave to you (use a hashset if you want).

static void Main(string[] args)
    {
        string test = " Mimi loves Toto and Tata hate Mimi so Toto killed Tata";
        foreach (string j in test.Split(' '))
        {
            if (j.Length > 0)
            {
                if (j.ToUpper()[0] == j[0])
                {
                    Console.WriteLine(j);
                }
            }
        }
        Console.ReadKey(); //Press any key to continue;
    }

Upvotes: 1

BFree
BFree

Reputation: 103740

I'm not sure why I'm posting this...

   string[] foo = "Mimi loves Toto and Tata hate Mimi so Toto killed Tata".Split(' ');
            HashSet<string> words = new HashSet<string>();
            foreach (string word in foo)
            {
                if (char.IsUpper(word[0]))
                {
                    words.Add(word);
                }
            }

            foreach (string word in words)
            {
                Console.WriteLine(word);
            }

Upvotes: 6

Related Questions