Author Topic: ToSentenceCase() Extension Method?  (Read 6350 times)

0 Members and 1 Guest are viewing this topic.

BlackBox

  • King Gator
  • Posts: 3770
ToSentenceCase() Extension Method?
« on: June 27, 2013, 06:50:15 PM »
I'm working on a project now that will require some string modification, and one that I'd like to include (which I am struggling with) is a ToSentenceCase() Extension Method.

The ToTitleCase() Extension Method was simple enough:
Code - C#: [Select]
  1. using System.Globalization;
  2. using System.Threading;
  3.  
  4. namespace System
  5. {
  6.     public static class ExtensionMethods
  7.     {
  8.         public static string ToTitleCase(this string str)
  9.         {
  10.             var cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
  11.             return cultureInfo.TextInfo.ToTitleCase(str.ToLower());
  12.         }
  13.     }
  14. }
  15.  
  16.  



... So any help with a ToSentenceCase() Extension Method would be greatly appreciated.
« Last Edit: June 27, 2013, 09:04:29 PM by BlackBox »
"How we think determines what we do, and what we do determines what we get."

BlackBox

  • King Gator
  • Posts: 3770
Re: ToSentenceCase() Extension Method?
« Reply #1 on: June 27, 2013, 09:03:39 PM »
Code from this post seems to be what I'm after, but I get an error when I convert it from VB to C# (lambda not being a delegate type), could anyone educate me as to how to correct this?

Admittedly, the code is over my head, and I'm simply trying to test it for viability:
Code - vb.net: [Select]
  1.     Public Shared Function SentenceCase(ByVal Input As String) As String
  2.         Dim SentenceBreakers As String = System.Text.RegularExpressions.Regex.Escape(".!?" & vbCrLf)
  3.         Dim Pattern As String = "((?<=^[^" & SentenceBreakers & "\w]{0,})[a-z]|(?<![" & SentenceBreakers & "])(?<=[" & SentenceBreakers & "][^" & SentenceBreakers & "\w]{0,})[a-z])"
  4.         Return System.Text.RegularExpressions.Regex.Replace(Input, Pattern, Function(m) m.Value(0).ToString().ToUpper() & m.Value.Substring(1))
  5.  
  6.     End Function
  7.  

... And here's the converted code from DeveloperFusion:
Code - C#: [Select]
  1. public static string SentenceCase(string Input)
  2. {
  3.         string SentenceBreakers = System.Text.RegularExpressions.Regex.Escape(".!?" + Constants.vbCrLf);
  4.         string Pattern = "((?<=^[^" + SentenceBreakers + "\\w]{0,})[a-z]|(?<![" + SentenceBreakers + "])(?<=[" + SentenceBreakers + "][^" + SentenceBreakers + "\\w]{0,})[a-z])";
  5.         return System.Text.RegularExpressions.Regex.Replace(Input, Pattern, m => m.Value(0).ToString().ToUpper() + m.Value.Substring(1));
  6.  
  7. }
  8.  
« Last Edit: June 27, 2013, 09:07:26 PM by BlackBox »
"How we think determines what we do, and what we do determines what we get."

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: ToSentenceCase() Extension Method?
« Reply #2 on: June 27, 2013, 09:06:44 PM »
Sounds complicated if you want something that will support names and acronyms. You could look up each word first, if it's in your dictionary then go to lower, if not then assume it's a name, or check it against a dictionary of acronyms.
A quick search tells me this is not a simple undertaking...

BlackBox

  • King Gator
  • Posts: 3770
Re: ToSentenceCase() Extension Method?
« Reply #3 on: June 27, 2013, 09:09:57 PM »
Thanks for the input, Will.

A quick search tells me this is not a simple undertaking...

The irony, being that this stemmed from TCASE.lsp, an Express Tool which 'does' offer sentence case as an option. Initially, albeit naively, I thought if 'LISP' can do it, why not in C#?

... And then I'm having to abuse Google, and get nada.
"How we think determines what we do, and what we do determines what we get."

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: ToSentenceCase() Extension Method?
« Reply #4 on: June 27, 2013, 09:22:23 PM »
As a hack compile the vb ciss then decompile in c#? Lol

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: ToSentenceCase() Extension Method?
« Reply #5 on: June 27, 2013, 11:04:45 PM »
The error in the code was m.Value(0) should have been m.Value[0]
When I run it it's only working on the first sentence  :| was missing the ^ from SentenceBreakers + "][^" + SentenceBreakers it works fine! it doesn't however modify what is in the middle of the sentence, just leaves it as is... so "aNNOYING CAPS" becomes "ANNOYING CAPS" :-D

Code - C#: [Select]
  1. public static string SentenceCase(string Input)
  2. {
  3.         string SentenceBreakers = System.Text.RegularExpressions.Regex.Escape(".!?" + Constants.vbCrLf);
  4.         string Pattern = "((?<=^[^" + SentenceBreakers + "\\w]{0,})[a-z]|(?<![" + SentenceBreakers + "])(?<=[" + SentenceBreakers + "][^" + SentenceBreakers + "\\w]{0,})[a-z])";
  5.         return System.Text.RegularExpressions.Regex.Replace(Input, Pattern, m => m.Value[0].ToString().ToUpper() + m.Value.Substring(1));
  6.  
  7. }
  8.  


good reference material: http://msdn.microsoft.com/en-us/library/az24scfc.aspx
« Last Edit: June 27, 2013, 11:29:58 PM by WILL HATCH »

BlackBox

  • King Gator
  • Posts: 3770
Re: ToSentenceCase() Extension Method?
« Reply #6 on: June 28, 2013, 01:55:31 AM »
Thanks, Will!

Regarding the mid-Caps, as with the ToTitleCase(), I'd speculate that it's necessary to supply string.ToLower()
"How we think determines what we do, and what we do determines what we get."

BlackBox

  • King Gator
  • Posts: 3770
Re: ToSentenceCase() Extension Method?
« Reply #7 on: June 28, 2013, 12:41:55 PM »
Regarding the mid-Caps, as with the ToTitleCase(), I'd speculate that it's necessary to supply string.ToLower()

I was correct in this, as supplying str.ToLower() resolves the unchanged uppercase letters, just like with the ToTitleCase() call:

Code - C#: [Select]
  1.         public static string ToSentenceCase(this String str)
  2.         {
  3.             string SentenceBreakers = Regex.Escape(".!?" + Constants.vbCrLf);
  4.             string Pattern =
  5.                 "((?<=^[^" + SentenceBreakers + "\\w]{0,})[a-z]|(?<![" +
  6.                 SentenceBreakers + "])(?<=[" + SentenceBreakers + "][^" +
  7.                 SentenceBreakers + "\\w]{0,})[a-z])";
  8.             return Regex.Replace(str.ToLower(), Pattern,
  9.                 m => m.Value[0].ToString().ToUpper() + m.Value.Substring(1));
  10.         }
  11.  

... Where "aNNOYING CAPS" now becomes "Annoying caps". Still not sure how this will work for formatted MText though.

In the mean time, I'm going to attempt to modify a copy of the above Lambda, to allow for if each letter is lowercase, make it uppercase, else lowercase... As part of a ToToggleCase() extension method (i.e., "tOGGLE cASE").

Cheers
"How we think determines what we do, and what we do determines what we get."

WILL HATCH

  • Bull Frog
  • Posts: 450

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: ToSentenceCase() Extension Method?
« Reply #9 on: July 16, 2013, 02:06:14 AM »
Have fun! Check out http://msdn.microsoft.com/en-us/library/system.windows.controls.spellcheck.aspx
It's a bit sorry that the SpellCheck class only seems to apply to a text control. It seems you thus need a texbox (even if only a temporary one) to spell check any piece of text.

Much like the 2nd alternative in this thread's 1st answer: http://stackoverflow.com/questions/14541038/spellcheck-class-in-code-behind

Wish MS opened a method like Hunspell's Spell, i.e. send it a string and have it check that. There must obviously be something like that in the class itself, it's probably just marked as private.

Anyhow, if this is meant for AutoCAD, you probably want something more in-line with that. I.e. using ACad's built-in spell checker. Especially since the notes in a usual drawing would have all sorts of acronyms and product names, most of which would show as spelling errors. At least using acad's DctCust dictionary there's a chance that the user already added these. But again, a wall faces us. The Developer help states that ACad's spelling engine is not accessible through DotNet: http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer%27s%20Guide/index.html?url=WS1a9193826455f5ff2566ffd511ff6f8c7ca-3a52.htm,topicNumber=d0e37779

So again, this would mean you need to temporarily make a text object with the string, then run the spell command on it an note the difference. Why should it be so difficult?  :roll: At least you can read the DctCust file into something like a hash-"array" (i.e. something like a Dictionary<string, object>, just leave object = null in all cases, then just use the ContainsKey method) - should be faster than even a sorted list. The "dict".cus file is just a text file with an item per line, so it shouldn't be too difficult to parse.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

BlackBox

  • King Gator
  • Posts: 3770
Re: ToSentenceCase() Extension Method?
« Reply #10 on: July 16, 2013, 09:59:39 AM »
Thanks for the info, Irne.  :-)

I'm still bummed that DatabaseServices.TextEditor.CreateTextEditor() only accepts an MText type.



Also worthy of note, is the small contingent of related extension methods I posted here stemming from this thread... Not perfect, could use the spelling/dictionary aspect, but does exactly what it says, and well for my needs.

Cheers
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6150
Re: ToSentenceCase() Extension Method?
« Reply #11 on: July 16, 2013, 10:12:23 AM »
I think InPlaceTextEditor will take DBText
 
http://www.theswamp.org/index.php?topic=43087.msg483058#msg483058

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: ToSentenceCase() Extension Method?
« Reply #12 on: July 16, 2013, 11:19:54 AM »
I remember this being strange on regular attributes, I suspect the same might hold true for regular text. The key I found was sending an objectid array to the Invoke method http://www.theswamp.org/index.php?topic=43908.msg491808#msg491808

BlackBox

  • King Gator
  • Posts: 3770
Re: ToSentenceCase() Extension Method?
« Reply #13 on: July 16, 2013, 11:30:48 AM »
Interesting, guys... I'll have to look into those.

Cheers
"How we think determines what we do, and what we do determines what we get."