This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 2 years ago.
My task is to find a specific word from a line by splitting with punctuation that can be anything (even a letter or any character in general). After finding the word, I have to return the word with punctuation that goes after it. I have come up with idea to firstly split line by punctuation, find each string that goes in between punctuation marks and then to split the same line only with words, but for some reason i only get the regular expression.
public static string FindWord2InLine(string line, string punctuation)
{
string[] parts = Regex.Split(line,"[" + punctuation + "]+");
string temp = "";
for (int i = 0; i < parts.Length; i++)
{
temp += Regex.Split(line, "[" + parts[i] + "]+");
}
return temp;
}
I think the the regex you want is \b[\w-]+?\b[,.] where ,. are your punctuation characters.
To break down the regex a little more:
\b is a word boundary.
[\w-] matches a word character (letter / number) or a hyphen.
+? matches the characters/hyphens at least once but as few as possible before the next boundary
Given the input Some words here. With some, punctuation... this makes three matches:
here.
some,
punctuation.
Since you are returning only a single string from your function, quite how you determine which of these matches to return is up to you.
You can use this code:
public static string FindWord2InLine(string line, string punctuation)
{
var matches = Regex.Matches(line, $"\\w+[{punctuation}]"); //match word with punctuation after it
string temp = "";
foreach (var match in matches)
{
temp += match; // perform action with word and punctuation
}
return temp;
}
Return of calling FindWord2InLine("foo, bar!,..,/ baz.", ",.!:") is foo,bar!baz.
Found out, that " Match withPunctuation = Regex.Match(line, temp + "[" + punctuation + "]+"); " Does The job
public static string FindWord2InLine(string line, string punctuation)
{
string[] parts = Regex.Split(line, "[" + punctuation + "]+");
int max = 0;
string temp = "";
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].Length > max) //If Longest Word
{
if ((parts[i].Length + 1) / 2 <= NumberOfDigits(parts[i])) // If atleast half of numbers are digits
{
temp = parts[i];
max = parts[i].Length;
}
}
}
Match withPunctuation = Regex.Match(line, temp + "[" + punctuation + "]+"); // matches line with word and punctuation
return withPunctuation.ToString();
}
Related
How do I do this with basic string functions and loop? I want to count the words in a string. My problem is that it only works when the user do not use multiple spaces.
Here is my code:
string phrase;
int word = 1;
Console.Write("Enter a phrase: ");
phrase = Console.ReadLine();
for (int i = 0; i<phrase.Length; i++)
{
if (name[i] == ' ')
{
word++;
}
}
Console.WriteLine(word);
One approach is to use a regular expression to "condense" all consecutive spaces into a single instance. Then the job is simple.
var str = "aaa bb cccc d e";
var regex = new Regex(#"\s+");
Console.WriteLine(regex.Replace(str, " ")?.Split(' ')?.Count());
If you can use LINQ, i suggest this approach:
string[] source = phrase.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
var matchQuery = from word in source
select word;
int wordCount = matchQuery.Count();
Console.WriteLine(wordCount);
I would create an array with string data type. Then I would use Split method when reading the data. This would split the entire text anytime you see a defined character (character is a one letter or character). In your case the defined character would be empty space; that is ' '. So my formula would be something like:
string phrase;
string[] seperated; // this is where you would split the full name
int word = 1;
Console.Write("Enter a phrase: ");
phrase = Console.ReadLine();
seperated=phrase.Split(' ');
for (int i = 0; i<seperated.Length; i++)
{
Console.WriteLine(seperated[i]); // this would print each word one by one
}
Once capture the full name split in seperated array, than you can use the seperated name, last name etc the way you want. seperated[0]= would be the first word, seperated[1] would be the second word... if the name consists of total 5 words than the last word could be reached by seperated[4].
Instead of the for loop you could use Split() and Linq:
var splitPhrase = phrase.Split(' ');
var wordCount = splitPhrase.Count(x=>x != "");
or use StringSplitOptions, as per comment:
var words = phrase.Split(' ', StringSplitOptions.RemoveEmptyEntrie);
var wordCount = words.Count();
You can use regex pattern:
\S matches anything but a whitespace
string str = "Test words test"
MatchCollection collection = Regex.Matches(str, #"[\S]+");
int numberOfWords = collection.Count;
First of all, we have to define word. If word is
Any non empty sequence of letters
we can use a simple regular expression pattern: \p{L}+
Code:
using System.Text.RegularExpressions;
...
int word = Regex.Matches(phrase, #"\p{L}+").Count;
Edit: in case you don't want regular expressions you can implement FSM - Finite State Machine:
int word = 0;
bool inWord = false;
foreach (var c in phrase)
if (char.IsLetter(c)) {
if (!inWord) // we count beginnings of each word
word += 1;
inWord = true;
}
else
inWord = false;
Here we have two states: - inWord == true, false - which are if character is within some word or not. Having these states we can count all the words beginnings.
You can achieve this by using the following function.It only returns the no. of words in the given sentence.
public int totalWords(string sentence) {
int wordCount = 0;
for (int i = 0; i < sentence.Length - 1; i++)
{
if (sentence[i] == ' ' && Char.IsLetter(sentence[i + 1]) && (i > 0))
{
wordCount++;
}
}
wordCount++;
return wordCount;
}
Assuming your words are separated by a space you can just Split the string and get the length of the resulting array:
string[] words = phrase.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
int numberOfWords = words.Length;
This is my code. How can I edit it to show every word which is at the odd position ONLY to be reversed?
for (int i = input.Length - 1; i >= 0; i--)
{
if (input[i] == ' ')
{
result = tmp + " " + result;
tmp = "";
}
else
tmp += input[i];
}
result = tmp + " " + result;
Console.WriteLine(result);
Example input:
"How are you today"
to output:
"How era you yadot"
Based on the position of a word ['How' -> 0] do not reverse; [are -> 1 odd index] Reverse
You can achieve it with the help of LINQ:
var input = "hello this is a test message";
var inputWords = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var result = string.Join(" ",
inputWords.Select((w, i) =>
i % 2 == 0
? w
: new string(w.Reverse().ToArray())
));
Where w in the select is the word, and i is the index, starting at 0 for the first word. % is the modulus operator and gets the remainder. If i % 2 == 0 (i.e. i can be divided by 2 with no remainder), then the original is returned. If there is a remainder (odd) then the reversed word is returned. Finally, it's all wrapped up in a string.Join(" ", items); which turns it back into a normal string rather than an array of items.
Try it online
So far you have a string, like this:
string input = "I want to reverse all odd words (odd words only!).";
And you, naturally, want to perform the task. Now it's the main question what's an odd word?
If you mean word's position (I at position 0, want at 1 - should be reversed etc.)
then you can use regular expressions to match words and Linq to process them:
using System.Linq; // To reverse single word
using System.Text.RegularExpressions; // To match the words within the text
...
// Let's elaborate the test example: add
// 1. some punctuation - ()!. - to preserve it
// 2. different white spaces (spaces and tabulation - \t)
// to add difficulties for naive algorithms
// 3. double spaces (after "to") to mislead split based algorithms
string input = "I want to reverse all\todd words (odd words only!).";
int index = 0; // words' indexes start from zero
string result = Regex.Replace(
input,
"[A-Za-z']+", // word is letters and apostrophes
match => index++ % 2 == 0
? match.Value // Even words intact
: string.Concat(match.Value.Reverse())); // Odd words reversed
Console.WriteLine(result);
If you want to reverse the words with odd Length, i.e. I, all, odd then all you have to do is to change the condition to
match => match.Value % 2 == 0
Outcome:
I tnaw to esrever all ddo words (ddo words ylno!).
Please, notice, that the punctuation has been preserved (only words are reversed).
OP: Based on the position of a word ['How' -> 0] do not reverse; [are -> 1 odd index] Reverse
public static void Main()
{
string input = "How are you today Laken-C";
//As pointed out by #Dmitry Bychenko string input = "How are you today";
//(double space after How) leads to How are uoy today outcome
input = Regex.Replace(input, #"\s+", " ");
var inp = input.Split(' ').ToList();
for (int j = 0; j < inp.Count(); j++)
{
if(j % 2 == 1)
{
Console.Write(inp[j].Reverse().ToArray());
Console.Write(" ");
}
else
Console.Write(inp[j] + " ");
}
}
OUTPUT:
DEMO:
dotNetFiddle
try this is perfect working code..
static void Main(string[] args)
{
string orgstr = "my name is sagar";
string revstr = "";
foreach (var word in orgstr.Split(' '))
{
string temp = "";
foreach (var ch in word.ToCharArray())
{
temp = ch + temp;
}
revstr = revstr + temp + " ";
}
Console.Write(revstr);
Console.ReadKey();
}
Output: ym eman si ragas
Hi I need to find longest sequence of words in text that's matching condition: if word is ending with letter N other word should start with letter N. N - could be any letter. For Example:
Simple Elephant
Apple Strong
So first line is matching my mentioned condition so I need to print it out to console.
Failing to think of an algorithm how this should work.
I make this code for you. Can answer to your questions.
List<string> sentenses = new List<string>();
sentenses.Add("hi, my name is Sam.");
sentenses.Add("Hi,is,settled,drums.");
sentenses.Add("Add all your sentenses here");
string longestSentense ="";
int longestCount = 0;
foreach(string sentense in sentenses)
{
string[] words = Regex.Split(sentense, "[^a-zA-Z]"); // cut sentense by all not letter character
int count = 0;
for (int i=0;i<words.Length-1;i++)
{
// check if last letter of words[i] is the same letter as the first or words[i+1]
if(words[i].Equals("") || words[i+1].Equals("")) continue; // don't look to "empty word"
if (words[i][words[i].Length-1].Equals(words[i + 1][0])) count++;
}
// if here is the biggest number of matching words, we save it
if(count>longestCount)
{
longestCount = count;
longestSentense = sentense;
}
}
Console.WriteLine("The sentence that contains the most of matching words : \n"
+ longestSentense + "\n"
+ " with " + longestCount + " junctions between matching words.");
Console.ReadKey();
I want to search a string for a word.
However, I don't want to get a result if the word searched is inside other word.
That is
I want this to return the number 7 (index of letter f):
findWord("Potato for you", "for")
but I want this to return -1 (i.e., not found)
findWord("Potato for you", "or")
If I use IndexOf, it will find the substring "or" inside the word "for".
Is there any simple way to do this?
char[] terminationCharacters = new char[] { '\n', '\t', ' ', '\r' };
//get array with each word to be taken into consideration
string[] words= s.Split(terminationCharacters, StringSplitOptions.RemoveEmptyEntries);
int indexOfWordInArray = Array.IndexOf(words, wordToFind);
int indexOfWordInS = 0;
for (int i = 0; i <= indexOfWordInArray; i++)
{
indexOfWordInS += words[i].Length;
}
return indexOfWordInS;
But this obviously may not work if there are multiple spaces between the words.
Is there any pre-built way to do this apparently simple thing, or should I just use a Regex?
You can use a regular expression:
var match = Regex.Match("Potato for you", #"\bfor\b");
if (match.Success)
{
int index = match.Index;
...
}
\b indicates a word boundary.
If you don't need the index but you just want to check if the word is in the string, you can use IsMatch, which returns a boolean, instead of Match.
If you're looking for the index, you can make a method like this. If you only want a bool whether or not it is in there, then the method would be a little simpler. More than likely, there could be a way to do this with a Regex easier, but they are not my forte.
I'll set it up as an extension method to make it easier to use.
public static int FindFullWord(this string search, string word)
{
if (search == word || search.StartsWith(word + " "))
{
return 0;
}
else if (search.EndsWith(" " + word))
{
return search.Length - word.Length;
}
else if (search.Contains(" " + word + " "))
{
return search.IndexOf(" " + word + " ") + 1;
}
else {
return -1;
}
}
I Have a string in the form "123456789".
While displaying it on the screen I want to show it as 123-456-789.
Please let me knwo how to add the "-" for every 3 numbers.
Thanks in Advance.
You can use string.Substring:
s = s.Substring(0, 3) + "-" + s.Substring(3, 3) + "-" + s.Substring(6, 3);
or a regular expression (ideone):
s = Regex.Replace(s, #"\d{3}(?=\d)", "$0-");
I'll go ahead and give the Regex based solution:
string rawNumber = "123456789";
var formattedNumber = Regex.Replace(rawNumber, #"(\d{3}(?!$))", "$1-");
That regex breaks down as follows:
( // Group the whole pattern so we can get its value in the call to Regex.Replace()
\d // This is a digit
{3} // match the previous pattern 3 times
(?!$) // This weird looking thing means "match anywhere EXCEPT the end of the string"
)
The "$1-" replacement string means that whenever a match for the above pattern is found, replace it with the same thing (the $1 part), followed by a -. So in "123456789", it would match 123 and 456, but not 789 because it's at the end of the string. It then replaces them with 123- and 456-, giving the final result 123-456-789.
You can use for loop also if the string length is not fixed to 9 digits as follows
string textnumber = "123456789"; // textnumber = "123456789012346" also it will work
string finaltext = textnumber[0]+ "";
for (int i = 1; i < textnumber.Length; i++)
{
if ((i + 1) % 3 == 0)
{
finaltext = finaltext + textnumber[i] + "-";
}
else
{
finaltext = finaltext + textnumber[i];
}
}
finaltext = finaltext.Remove(finaltext.Length - 1);