我必须使用此代码多次循环,是否有更好的方法?
@EnableMongoRepositories
或
@Configuration
或
item = '!@#$abc-123-4;5.def)(*&^;\n'
我这样的人没用
'!@#$abc-123-4;5.def)(*&^;\n_'
期望
'!@#$abc-123-4;5.def)_(*&^;\n_'
最终目标是仅从两端除去所有非item = re.sub('^\W|\W$', '', item)
的字符,同时在它们之间保留任何字符。第一个字母和最后一个字母在abc-123-4;5.def
答案 0 :(得分:10)
This expression不受左侧限制,如果所有所需的字符都与问题中的示例相似,则速度可能更快:
([a-z0-9;.-]+)(.*)
我假设您可能只想过滤输入字符串左右两侧的特殊字符。
您可以在此表达式中添加更多字符和边界,如果愿意,甚至可以将其更改为更简单,更快的表达式。
此图显示了表达式的工作方式,您可以在此link中可视化其他表达式:
如果您想在右侧添加边界,只需执行以下操作:
([a-z0-9;.-]+)(.*)$
或者甚至可以在捕获组的左右列出您的特殊字符。
const regex = /([a-z0-9;.-]+)(.*)$/gm;
const str = `!@#\$abc-123-4;5.def)(*&^;\\n`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
此JavaScript代码段使用简单的100万次for
循环来显示该表达式的性能。
const repeat = 1000000;
const start = Date.now();
for (var i = repeat; i >= 0; i--) {
const string = '!@#\$abc-123-4;5.def)(*&^;\\n';
const regex = /([!@#$)(*&^;]+)([a-z0-9;.-]+)(.*)$/gm;
var match = string.replace(regex, "$2");
}
const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ");
# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility
import re
regex = r"([a-z0-9;.-]+)(.*)$"
test_str = "!@#$abc-123-4;5.def)(*&^;\\n"
matches = re.finditer(regex, test_str, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
for groupNum in range(0, len(match.groups())):
groupNum = groupNum + 1
print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))
# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
Match 1 was found at 4-27: abc-123-4;5.def)(*&^;\n
> Group 1 found at 4-19: abc-123-4;5.def
Group 2 found at 19-27: )(*&^;\n
答案 1 :(得分:5)
您可以通过在字符集的开头使用克拉^
字符来取反其内容来完成此操作。 [^a-zA-Z0-9]
将匹配任何非字母或数字的内容。
^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$
答案 2 :(得分:4)
从开始/结束处修剪非单词字符(\W
的上方),并添加属于单词字符 [A-Za-z0-9_]
的下划线可以将_
与\W
一起放到character class中。
^[\W_]+|[\W_]+$
See demo at regex101。这与@CAustin的答案和@sln的评论非常相似。
要求逆并匹配从第一个到最后一个字母数字字符的所有内容:
[^\W_].*[^\W_]|[^\W_]
使用re.DOTALL
表示多行字符串。正则表达式无需尝试[\s\S]*
instead of .*
Another demo at regex101。 |[^\W_]
用于其中包含just one alnum的字符串。
答案 3 :(得分:3)
首先,您可以通过删除转义字符来消除一些非常特殊的情况:
item = re.sub(r'\\[abnrt]', '', item)
然后,从获得的_
中删除\W
中的[^a-zA-Z0-9]
字符。
您的最终正则表达式将为:(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)
item = re.sub(r'(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)', '', item)