javascript - 在特定单词后断开字符串并保留在新行上(正则表达式)

标签 javascript jquery html regex string

假设我有一个文本字段,用户可以在其中提交代码片段。我想检测特定单词何时出现在字符串中,然后对该单词之后的单词/字符执行某些操作。

假设我们有一个字符串,在单词 pyjamas 之后,我想在一个新行上开始其余代码,没有缩进。 (与代码美化器的工作方式非常相似。)输出将在 pre 内呈现。 ,所以我不想要任何 <br>标签或其他 HTML 标签。

不过还是有一些问题。

  1. 单词 (pyjamas) 之后的所有内容都必须另起一行,与前一行处于同一“级别”(等量的制表符缩进)。
  2. 逗号应始终在新行开始并使用制表符反向缩进
  3. 如果有其他字符,就说感叹号! ,下面的代码必须另起一行,并以制表符作为缩进。

例子:

输入:

Bananas! Apples and pears walk down pyjamas the street! and they say pyjamas hi to eachother, pyjamas But then! some one else comes pyjamas along pyjamas Who is he?, pyjamas I don't know who! he is pyjamas whatever,,

输出:

Bananas!
    Apples and pears walk down pyjamas
    the street!
        and they say pyjamas
        hi to eachother
    , pyjamas
    But then!
        some one else comes pyjamas
        along pyjamas
        Who is he?
    , pyjamas
    I don't know who!
        he is pyjamas
        whatever
    ,
,

我正在使用 jQuery,因此您可以根据需要使用它。

这是上面代码的 fiddle ,所以你可以测试一下。 My result到目前为止一点都不好。 (在 textarea 中输入一些内容,输出会发生变化。)由于我目前对正则表达式知之甚少,因此我需要一些帮助。

我目前拥有的:

var a = $("textarea").val(),
    b = a.split('!').join("!\n  "),
    c = b.split('pyjamas').join("pyjamas \n");

$("textarea").keyup(function() {
    $("#output>pre").html(c);
});

最佳答案

这是一个简单的方法,不需要递归函数,甚至可以在没有正则表达式的情况下完成(但我发现它们在这里很方便)。

function indent(str)
{
    var tabs = function(n) { return new Array(n+1).join('\t'); }

    var tokens = str.match(/!|,|pyjamas|(?:(?!pyjamas)[^!,])+/g);
    var depth = 0;
    var result = '';
    for (var i = 0; i < tokens.length; ++i)
    {
        var token = tokens[i];
        switch(token)
        {
        case '!':
            ++depth;
            result += token + '\n' + tabs(depth);
            break;
        case ',':
            --depth;
            result += '\n' + tabs(depth) + token;
            break;
        case 'pyjamas':
            result += token + '\n' + tabs(depth);
            break;
        default:
            result += token;
            break;
        }
    }
    return result;
}

首先,我们定义了一个函数,它返回一串 n 制表符(为了方便起见)。

然后我们将这个过程分成两个步骤。首先,我们将字符串标记化——也就是说,我们将其拆分为 !pyjamas 和其他任何内容。 (最后有对正则表达式的解释,但您也可以通过其他方式进行标记化。)然后我们只需一个接一个地遍历标记,将当前缩进级别保持在 depth 中。

  • 如果是 !,我们增加深度,打印 !,一个换行符和制表符。
  • 如果是 ,,我们减少深度,打印换行符、制表符,然后是 ,
  • 如果是 pyjamas,我们只需打印它、一个换行符和制表符。
  • 如果是其他任何东西,我们只打印该 token 。

就是这样。您可能想要添加一些健全性检查以确保深度不会变为负值(即您的 ,! 多)- 目前只会在没有任何选项卡的情况下呈现,但是之后你需要编写额外的 ! 才能使深度恢复到 1。这很容易处理,但我不知道你对此有什么假设或要求。

它还没有处理换行符后的额外空格(请参阅最后的编辑)。

Working demo.

现在是正则表达式:

/
  !               # Match a literal !
|                 # OR
  ,               # Match a literal ,
|                 # OR
  pyjamas         # Match pyjamas
|                 # OR
  (?:             # open a non-capturing group
    (?!pyjamas)   # make sure that the next character is not the 'p' of 'pyjamas'
    [^!,]         # match a non-!, non-, character
  )+              # end of group, repeat once or more (as often as possible)
/g

g 查找所有匹配项(而不是只查找第一个匹配项)。 ECMAScript 6 将附带一个 y modifier ,这将使标记化变得更加容易 - 但令人讨厌的是,这个 y 修饰符是 ECMAScript 自己的发明,而提供此功能的所有其他风格都在模式中使用 \G anchor 。

如果您不熟悉正则表达式中的一些更高级的概念,我建议您引用这个很棒的教程:

编辑:

这是一个更新版本,修复了我提到的关于换行后空格的上述警告。在处理结束时,我们只需删除制表符后的所有空格:

result = result.replace(/^(\t*)[ ]+/gm, '$1');

正则表达式匹配一行的开头,然后捕获零个或多个制表符,然后是尽可能多的空格。空格周围的方括号不是必需的,但可以提高可读性。修饰符 g 再次查找所有此类匹配项,m 使 ^ 在行首匹配(而不是仅在行首字符串)。在替换字符串中,$1 指的是我们在括号中捕获的内容 - 即所有这些选项卡。因此,写回制表符但吞下空格。

Working demo.

关于javascript - 在特定单词后断开字符串并保留在新行上(正则表达式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22259272/

相关文章:

javascript - 在 JavaScript 中打开新窗口

javascript - 如何使 Angular JS 中的 ng-repeat 语句运行有限次数

javascript - 使用 JavaScript 获取表单中输入字段的值

jquery - 修复错误后如何隐藏错误消息?

javascript - JQuery 插件可以在 JQuery 方法链上调用吗?还是需要在选择器之后直接调用?

java - 如何使用 JSP 更新 XML 文件

jquery - 使用 JQuery、HTML 和 CSS 无需重新加载页面即可更改内容淡出/淡入和 css

javascript - 有没有办法在两个不同的页面之间制作动画滚动过渡?

javascript - 如何将CSS应用到bootstrap Affix navbar

javascript - req.body.username 未输出正确的值