假设我有一个文本字段,用户可以在其中提交代码片段。我想检测特定单词何时出现在字符串中,然后对该单词之后的单词/字符执行某些操作。
假设我们有一个字符串,在单词 pyjamas 之后,我想在一个新行上开始其余代码,没有缩进。 (与代码美化器的工作方式非常相似。)输出将在 pre
内呈现。 ,所以我不想要任何 <br>
标签或其他 HTML 标签。
不过还是有一些问题。
- 单词 (pyjamas) 之后的所有内容都必须另起一行,与前一行处于同一“级别”(等量的制表符缩进)。
- 逗号应始终在新行开始并使用制表符反向缩进
- 如果有其他字符,就说感叹号
!
,下面的代码必须另起一行,并以制表符作为缩进。
例子:
输入:
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
。这很容易处理,但我不知道你对此有什么假设或要求。
它还没有处理换行符后的额外空格(请参阅最后的编辑)。
现在是正则表达式:
/
! # 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
指的是我们在括号中捕获的内容 - 即所有这些选项卡。因此,写回制表符但吞下空格。
关于javascript - 在特定单词后断开字符串并保留在新行上(正则表达式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22259272/