Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript正则表达式用单词的第一个字母替换单词,括号内的情况除外_Javascript_Regex_Replace_Parentheses - Fatal编程技术网

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,

我正在寻找JavaScript正则表达式,它将用每个单词的第一个字母替换文本块中的单词,但如果括号中有单词,请将它们保留在括号中。 其目的是创建一种记忆装置,用于记忆剧本或戏剧剧本中的台词。我希望实际行减少到第一个字母,但阶段的方向(括号中)是不变的

例如:

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"

在这种情况下,有三种方法:

  • 使用regexp查找所有要保留的内容,然后将这些内容粘贴在一起

  • 使用regexp找到你不想保留的东西,然后通过替换它们(这是其他一些答案所做的)将它们扔掉

  • 正如一个答案所示,自己解析字符串

  • <>我们将考虑ReGEXP解决方案。编写ReXEXP的关键是写下你想要它做什么的叙述描述。然后将它转换成实际的ReXEP语法。否则,当你随机尝试一个或另一个事物时,你的眼睛就会开始流血。

    要找到您想要保留的内容,叙述性描述如下:

    任何带括号的字符串(包括前面的空格)空格(或字符串开头),后跟单个字母、标点符号

    要将其转换为regexp,请执行以下操作:

    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;iconsole.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('')
      ;
    }