I took a stab at this... my goal was to do something lightweight that wouldn't require additional libraries, and would give each developer the ability to control a few necessary elements - such as padding certain chars, using negative contractions as first word position only, and allowing for common question elements. I created two functions, that when you pass in a value from an Angular6 HTML page, it does a pretty good job for most of my cases...
I don't include "don't" as a starter word because it can be a statement as many times as a question. Don't you think?
Angular HTML:
<input matInput type="text" placeholder="{{Prompt}}" [(ngModel)]="value">
.ts functions:
isQuestion(sentence: string = this.value){
var q_elements : string[] = ["who", "what", "when", "where", "why", "how", "?"];
var q_starters : string[] = ["which", "won't", "can't", "isn't", "aren't", "is", "do", "does", "will", "can", "is"];
var temp = sentence.toLowerCase();
var padChars : string[] = ["?", "-", "/"];
var i : number = 0;
for (i=0; i < padChars.length; i++) {
temp = this.padChar(temp, padChars[i]);
}
var splitted = temp.split(" ");
// console.log(splitted);
if (q_starters.includes(splitted[0])) {
// console.log('found a question with a starter');
return true;
} else {
return q_elements.some(function (v) {
return splitted.indexOf(v) >= 0;
});
}
}
padChar(myString : string, myChar : string) {
var position = myString.indexOf(myChar);
var output : string = myString;
while(position > 0 && position < output.length) {
if (output.charAt(position - 1) != " ") {
output = [output.slice(0, position), " ", output.slice(position)].join('');
position = output.indexOf(myChar, position);
}
if (position + 1 < output.length) {
if (output.charAt(position + 1) != " ") {
output = [output.slice(0, (position + 1)), " ", output.slice(position + 1)].join('');
position = output.indexOf(myChar, position);
}
}
position = output.indexOf(myChar, position + 1);
}
return output;
}