行的正则表达式查询

时间:2017-09-19 01:41:25

标签: regex

我试图找出以下情况的几个正则表达式:

  • 长度可被n整除的行,但对于整数n和m
  • 而言不是m
  • 不包含给定字符的特定数量n的行,
    但可能含有更多或更少

我是新来者,并希望对这些做出任何澄清。

1 个答案:

答案 0 :(得分:0)

我在我的例子中使用了JavaScript。

对于第一个关键是注意'倍数'只是重复。因此,使用/(...)+/将匹配3个字符,然后尽可能多次重复该匹配。每个匹配组不需要是3个字符的同一组,但它们确实需要是连续的。使用^$进行适当的锚定可确保您检查确切的字符串长度,?:可用于否定。

e.g。多个5但不是3:

/^(?!(.{3})+$)(.{5})+$/gm

请注意,JavaScript使用/标记表达式的开头和结尾,gm是用于执行全局多行匹配的修饰符。我不清楚匹配'lines'是什么意思所以我假设字符串本身包含必须考虑的换行符。如果你有,比方说和行数组,并且可以单独检查每一行,那么事情会变得容易一些,或者在第二个问题的情况下容易得多。

第一个问题的演示:

var chars = '12345678901234567890',
    str = '';

for (var i = 1 ; i <= chars.length ; ++i) {
    str += chars.slice(0, i) + '\n';
}

console.log('Full text is:');
console.log(str);

console.log('Lines with length that is a multiple of 2 but not 3:');
console.log(lineLength(str, 2, 3));

console.log('Lines with length that is a multiple of 3 but not 2:');
console.log(lineLength(str, 3, 2));

console.log('Lines with length that is a multiple of 5 but not 3:');
console.log(lineLength(str, 5, 3));


function lineLength(str, multiple, notMultiple) {
    return str.match(new RegExp('^(?!(.{' + notMultiple + '})+$)(.{' + multiple + '})+$', 'gm'));
}

对于第二个问题,我无法想出一个很好的方法。这个恐怖表演是我最终的结果。在一行中匹配n个特定字符的匹配并不是太糟糕,但匹配“非n”证明是困难的。我最终匹配{0,n-1}{n+1,},但整件事对我来说并不是那么好。我怀疑有一种更聪明的方式,我目前没有看到它。

var str = 'a\naa\naaa\naaaa\nab\nabab\nababab\nabababab\nba\nbab\nbaba\nbbabbabb';

console.log('Full string:');
console.log(str);

console.log('Lines with 1 occurrence of a:');
console.log(mOccurrences(str, 'a', 1));

console.log('Lines with 2 occurrences of a:');
console.log(mOccurrences(str, 'a', 2));

console.log('Lines with 3 occurrences of a:');
console.log(mOccurrences(str, 'a', 3));

console.log('Lines with not 1 occurrence of a:');
console.log(notMOccurrences(str, 'a', 1));

console.log('Lines with not 2 occurrences of a:');
console.log(notMOccurrences(str, 'a', 2));

console.log('Lines with not 3 occurrences of a:');
console.log(notMOccurrences(str, 'a', 3));


function mOccurrences(str, character, m) {
    return str.match(new RegExp('^[^' + character + '\n]*(' + character + '[^' + character + '\n]*){' + m + '}[^' + character + '\n]*$', 'gm'));
}

function notMOccurrences(str, character, m) {
    return str.match(new RegExp('^([^' + character + '\n]*(' + character + '[^' + character + '\n]*){0,' + (m - 1) + '}[^' + character + '\n]*|[^' + character + '\n]*(' + character + '[^' + character + '\n]*){' + (m + 1) + ',}[^' + character + '\n]*)$', 'gm'));
}

其工作原理的关键在于它尝试查找由a的序列分隔的[^a]次出现,其中\n被引入以阻止它走到下一行。

在现实世界中,我可能会首先将分割成行,因为这会使事情变得更容易。计算特定字符的出现次数就是:

str.replace(/[^a]/g, '').length;

// Could use this instead but note in JS it'd fail if length is 0
str.match(/a/g, '').length;

同样,这假设一个JavaScript环境。如果你在一个环境中使用正则表达式,你真的只能将正则表达式作为参数传递,那么它就会回到我之前的恐怖节目中。