JavaScript正则表达式用单词的第一个字母替换单词,括号内的情况除外
我正在寻找JavaScript正则表达式,它将用每个单词的第一个字母替换文本块中的单词,但如果括号中有单词,请将它们保留在括号中。 其目的是创建一种记忆装置,用于记忆剧本或戏剧剧本中的台词。我希望实际行减少到第一个字母,但阶段的方向(括号中)是不变的 例如:JavaScript正则表达式用单词的第一个字母替换单词,括号内的情况除外,javascript,regex,replace,parentheses,Javascript,Regex,Replace,Parentheses,我正在寻找JavaScript正则表达式,它将用每个单词的第一个字母替换文本块中的单词,但如果括号中有单词,请将它们保留在括号中。 其目的是创建一种记忆装置,用于记忆剧本或戏剧剧本中的台词。我希望实际行减少到第一个字母,但阶段的方向(括号中)是不变的 例如: Test test test (test). Test (test test) test test. 将产生以下结果: T t t (test). T (test test) t t. 使用: .replace(/(\w)\w*/g,
Test test test (test). Test (test test) test test.
将产生以下结果:
T t t (test). T (test test) t t.
使用:
.replace(/(\w)\w*/g,'$1')
收益率:
T t t (t). T (t t) t t.
我对正则表达式的理解很差。我已经研究了好几天了,尝试了很多方法,但似乎无法找到解决方案。为了达到预期的效果,需要使用捕获组和前瞻断言
> "Test test test (test). Test (test test) test test".replace(/(^[^\s(]|\s[^\s(])[^()\s]*(?=\s|$)/g, "$1")
'T t t (test). T (test test) t t'
捕获每个单词的第一个字母,该字母不能是空格或(^[^\s(]|\s[^\s(])
)(
匹配任何字符,但不匹配[^()\s]*
或(
或空格)
正向先行断言匹配后必须有空格或行尾锚点,这反过来意味着我们匹配了一个完整的单词(?=\s |$)
/(\w|\([^)]+\))\w*/
添加的部分\([^]+\)
匹配两对括号内的所有内容
"Test test test (test). Test (test test) test test.".replace(/(\w|\([^)]+\))\w*/g,'$1')
>"T t t (test). T (test test) t t."
编辑:解决评论中提出的问题
"Test test test (test). Test (test. test.) test test. test(test) (test)test".replace(/(\w|\([^)]+)\w*/g,'$1')
>"T t t (test). T (test. test.) t t. t(test) (test)t"
在这种情况下,有三种方法:
including preceding spaces: \s*
any parenthesized string: \(.*?\)
or: |
space or beginning of string: (^|\s+)
any letter: \w
punctuation: [.]
因此,相关的regexp是/\s*\(.*?\)|(^ |\s+)\w |[.]/
>> parts = str.match(/\s*\(.*?\)|(^|\s+)\w/g);
<< ["T", " t", " t", " (test)", ".", " T", " (test test)", " t", " t", "."]
>> parts.join('')
<< "T t t (test). T (test test) t t."
因此,整个解决方案变得更加简单
function abbreviate_words_outside_parentheses(str) {
return str .
split(/(\(.*?\)|\s+|[.])/) .
filter(Boolean) .
map(function(piece) { return piece[0] === '(' ? piece : piece[0]; }) .
join('')
;
}
如果您认为将来可能需要执行其他类型的转换(使用regexp可能很难处理),则此过程方法可能更可取。为了使正则表达式保持简单,可以使用回调机制跟踪开始括号和结束括号:
var t='Test(Test).Test(Test)Test(Test)Test;
//跟踪打开状态和上次索引
变量s={
开:错,
索引:0
};
var res=t.replace(/\w+/g,函数($0,索引){
//更新状态
对于(var i=s.index;i console.log(res);
尽可能紧凑,但如果有问题的话,当右括号后面没有空格时将失败。例如,Test(Test)Test“
产生“T(Test)T”
@torazaburo:确实如此,但这个问题可以用非单词边界轻松解决:(\w| \([^)]*\)\B\w*
@Casimir et Hippolyte:如果建议使用非单词边界,则当非括号中的单词紧跟在右括号之后时,而不是紧跟在右括号之前时,括号中的文本仅作为其第一个字母。例如,“test(test)(test)(test)test”产生“t(test)(t)t”@Grewu:使其成为可选:(\w| \([^)]*\)(?:\B\w+)
@dwickern:\B
不是字符,您不能将其放入字符类,也没有必要。省略右括号是个好主意。如何修改这些解决方案以在结果中包含所需的标点符号?我修改了您的添加内容,以包含感叹号和问号“[。!\?]“。现在,“拆分”示例适用于我能想象的任何场景。第一个示例适用于所有场景,除非右括号和下一个单词之间没有空格。因此,虽然Test(Test)生成T(Test),但Test(Test)只生成(Test)。这种情况可能很少出现。这正是我所需要的。
function abbreviate_words_outside_parentheses(str) {
return str .
split(/(\(.*?\)|\s+|[.])/) .
filter(Boolean) .
map(function(piece) { return piece[0] === '(' ? piece : piece[0]; }) .
join('')
;
}