如果单词的第一个字符前面没有特殊字符序列,如何将其大写?
How to uppercase the first character of a word if it was not preceded or prefixed by a special character sequence?
我正在编写 JavaScript 代码。目的是在输入 textarea
.
时,使句点字符 (Hello world. Hi
) 之后的每个单词的第一个字符大写
为此,我正在使用以下代码……
$('#div2').on('input', function (evt) {
var re = /(^|[.!?]\s+)([a-z])/g;
var box = evt.target;
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
var val = $(evt.target).val().replace(re, function (m, , ) {
return + .toUpperCase()
});
$(evt.target).val(val);
box.setSelectionRange(stringStart, stringEnd);
});
按预期工作。
但现在我希望它应该跳过一些像 (U.S.A.) 这样的词。如果输入单词 U.S.A。在 textare 中,下一个单词的第一个字符不应大写。
E.g.
U.S.A. is the //Expected
U.S.A. Is the //what i am getting (wrong)
为了实现这个,我写了下面的代码,但没有按预期工作。
var skipWordUpper = ['U.S.A.', 'Inc.'];
$('#div2').on('input', function (evt) {
var re = /(^|[.!?]\s+)([a-z])/g;
var box = evt.target;
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
var str = $('#div2').val();
var beforeSpace = str.split(" ").splice(-2)
var foundPresent = $.inArray(beforeSpace[0], skipWordUpper) > -1;
if (!foundPresent) {
var val = $(evt.target).val().replace(re, function (m, , ) {
return + .toUpperCase()
});
$(evt.target).val(val);
box.setSelectionRange(stringStart, stringEnd);
}
});
任何人都会帮助找出我犯了什么错误并让我以正确的方式。
或常规 exp 的任何更改。是必须的。
为我对 JAVASCRIPT
的肚皮知识道歉
尝试使用负向回顾来排除正则表达式中的那些词:
$('#div2').on('input', function(evt) {
var re = /(?<!U.S.A|Inc)([.!?]\s+)([a-z])/g;
var box = evt.target;
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
var str = $('#div2').val();
var val = $(evt.target).val().replace(re, function(m, , ) {
return + .toUpperCase()
});
$(evt.target).val(val);
box.setSelectionRange(stringStart, stringEnd);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="div2"></textarea>
一种基于类似于例如...
/(?<!\b(?:inc|pease|nope|U\.S\.A|u\.s\.w))([.?!]\s+)(\w)/gi
由于 OP 正在寻找一种 白名单-黑名单 支持,因此必须采用可靠的方法来清理此类字符串项。必须从这样的列表动态构建正则表达式。因此,在允许正则表达式(搜索)模式成为正则表达式(搜索)模式的一部分之前,需要对正则表达式特定的控制字符进行转义,然后将其传递给 RegExp
构造函数。
另请注意 lookbehind assertions according to MDN and to caniuse 在常用的 JS 引擎中并不完全受支持,尤其是在将正则表达式的完整语法应用于后视时,如以下测试用例所示......
function toRegExpSearch(str) {
return String(str)
.replace((/[$^*+?!:=.|(){}[\]\]/g), match => `\${ match }`)
.replace((/\s+/g), '\s+');
}
const regXFirstWordCharAfterFullstop = (/([.?!]\s+)(\w)/g);
let regXFirstWordCharAfterFullstopException = null;
// please also have a look into ... [https://regex101.com/r/zQ1gzo/1/]
function updateFullstopExceptionRegX(evt) {
const exceptionPattern = evt.currentTarget.value
.trim()
.split(/\s*,\s*|\s+/)
.map(str => toRegExpSearch(str.replace((/\.$/g), '')))
.join('|');
regXFirstWordCharAfterFullstopException = (exceptionPattern !== '')
? RegExp(`(?<!\b(?:${ exceptionPattern }))([.?!]\s+)(\w)`, 'gi')
: null;
document
.querySelector('#regx')
.textContent = String(regXFirstWordCharAfterFullstopException);
sanitizeText({
currentTarget: document.querySelector('#text')
});
}
function sanitizeText(evt) {
const textElm = evt.currentTarget;
const { selectionStart, selectionEnd } = textElm;
textElm.value = (regXFirstWordCharAfterFullstopException === null)
? textElm.defaultValue
: textElm.value
.replace(
regXFirstWordCharAfterFullstop,
(_, , ) => + .toLowerCase()
)
.replace(
regXFirstWordCharAfterFullstopException,
(_, , ) => + .toUpperCase()
);
textElm.setSelectionRange(selectionStart, selectionEnd);
}
function init() {
document
.querySelector('#skiplist')
.addEventListener('input', updateFullstopExceptionRegX);
document
.querySelector('#text')
.addEventListener('input', sanitizeText);
updateFullstopExceptionRegX({
currentTarget: document.querySelector('#skiplist')
});
sanitizeText({
currentTarget: document.querySelector('#text')
});
}
init();
input, textarea {
display: block;
width: 100%;
margin: 0;
}
pre { margin: 3px 0; padding: 0; }
<input id='skiplist' type="text" placeholder="... add word or abbreviation to skiplist ..." value="inc. pease, nope, U.S.A. u.s.w." />
<pre><code id="regx">(/(?:)/)</code></pre>
<textarea cols="40" rows="9" id="text" placeholder="...type or paste text freely...">
U.S.A. Is the country? i want to live in. if you please. yes. nope.
U.S.A. Is the country? i want to live inc. If you pease. Dope. yes.
U.S.A. Is the country? i want to live Inc. If you pease. Dope. yes.
u.s.w. And so on. a German abbreviation.
u.s.w. And so on. a German abbreviation.
</textarea>
我正在编写 JavaScript 代码。目的是在输入 textarea
.
Hello world. Hi
) 之后的每个单词的第一个字符大写
为此,我正在使用以下代码……
$('#div2').on('input', function (evt) {
var re = /(^|[.!?]\s+)([a-z])/g;
var box = evt.target;
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
var val = $(evt.target).val().replace(re, function (m, , ) {
return + .toUpperCase()
});
$(evt.target).val(val);
box.setSelectionRange(stringStart, stringEnd);
});
按预期工作。 但现在我希望它应该跳过一些像 (U.S.A.) 这样的词。如果输入单词 U.S.A。在 textare 中,下一个单词的第一个字符不应大写。
E.g.
U.S.A. is the //Expected
U.S.A. Is the //what i am getting (wrong)
为了实现这个,我写了下面的代码,但没有按预期工作。
var skipWordUpper = ['U.S.A.', 'Inc.'];
$('#div2').on('input', function (evt) {
var re = /(^|[.!?]\s+)([a-z])/g;
var box = evt.target;
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
var str = $('#div2').val();
var beforeSpace = str.split(" ").splice(-2)
var foundPresent = $.inArray(beforeSpace[0], skipWordUpper) > -1;
if (!foundPresent) {
var val = $(evt.target).val().replace(re, function (m, , ) {
return + .toUpperCase()
});
$(evt.target).val(val);
box.setSelectionRange(stringStart, stringEnd);
}
});
任何人都会帮助找出我犯了什么错误并让我以正确的方式。 或常规 exp 的任何更改。是必须的。 为我对 JAVASCRIPT
的肚皮知识道歉尝试使用负向回顾来排除正则表达式中的那些词:
$('#div2').on('input', function(evt) {
var re = /(?<!U.S.A|Inc)([.!?]\s+)([a-z])/g;
var box = evt.target;
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
var str = $('#div2').val();
var val = $(evt.target).val().replace(re, function(m, , ) {
return + .toUpperCase()
});
$(evt.target).val(val);
box.setSelectionRange(stringStart, stringEnd);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="div2"></textarea>
一种基于类似于例如...
/(?<!\b(?:inc|pease|nope|U\.S\.A|u\.s\.w))([.?!]\s+)(\w)/gi
由于 OP 正在寻找一种 白名单-黑名单 支持,因此必须采用可靠的方法来清理此类字符串项。必须从这样的列表动态构建正则表达式。因此,在允许正则表达式(搜索)模式成为正则表达式(搜索)模式的一部分之前,需要对正则表达式特定的控制字符进行转义,然后将其传递给 RegExp
构造函数。
另请注意 lookbehind assertions according to MDN and to caniuse 在常用的 JS 引擎中并不完全受支持,尤其是在将正则表达式的完整语法应用于后视时,如以下测试用例所示......
function toRegExpSearch(str) {
return String(str)
.replace((/[$^*+?!:=.|(){}[\]\]/g), match => `\${ match }`)
.replace((/\s+/g), '\s+');
}
const regXFirstWordCharAfterFullstop = (/([.?!]\s+)(\w)/g);
let regXFirstWordCharAfterFullstopException = null;
// please also have a look into ... [https://regex101.com/r/zQ1gzo/1/]
function updateFullstopExceptionRegX(evt) {
const exceptionPattern = evt.currentTarget.value
.trim()
.split(/\s*,\s*|\s+/)
.map(str => toRegExpSearch(str.replace((/\.$/g), '')))
.join('|');
regXFirstWordCharAfterFullstopException = (exceptionPattern !== '')
? RegExp(`(?<!\b(?:${ exceptionPattern }))([.?!]\s+)(\w)`, 'gi')
: null;
document
.querySelector('#regx')
.textContent = String(regXFirstWordCharAfterFullstopException);
sanitizeText({
currentTarget: document.querySelector('#text')
});
}
function sanitizeText(evt) {
const textElm = evt.currentTarget;
const { selectionStart, selectionEnd } = textElm;
textElm.value = (regXFirstWordCharAfterFullstopException === null)
? textElm.defaultValue
: textElm.value
.replace(
regXFirstWordCharAfterFullstop,
(_, , ) => + .toLowerCase()
)
.replace(
regXFirstWordCharAfterFullstopException,
(_, , ) => + .toUpperCase()
);
textElm.setSelectionRange(selectionStart, selectionEnd);
}
function init() {
document
.querySelector('#skiplist')
.addEventListener('input', updateFullstopExceptionRegX);
document
.querySelector('#text')
.addEventListener('input', sanitizeText);
updateFullstopExceptionRegX({
currentTarget: document.querySelector('#skiplist')
});
sanitizeText({
currentTarget: document.querySelector('#text')
});
}
init();
input, textarea {
display: block;
width: 100%;
margin: 0;
}
pre { margin: 3px 0; padding: 0; }
<input id='skiplist' type="text" placeholder="... add word or abbreviation to skiplist ..." value="inc. pease, nope, U.S.A. u.s.w." />
<pre><code id="regx">(/(?:)/)</code></pre>
<textarea cols="40" rows="9" id="text" placeholder="...type or paste text freely...">
U.S.A. Is the country? i want to live in. if you please. yes. nope.
U.S.A. Is the country? i want to live inc. If you pease. Dope. yes.
U.S.A. Is the country? i want to live Inc. If you pease. Dope. yes.
u.s.w. And so on. a German abbreviation.
u.s.w. And so on. a German abbreviation.
</textarea>