在字母数字字符之间以分号分隔
Posted
技术标签:
【中文标题】在字母数字字符之间以分号分隔【英文标题】:Split on semicolon in between alphanumeric characters 【发布时间】:2018-01-16 05:02:24 【问题描述】:假设我们有这些字符串:
1. "a;b;c;d;e"
2. "1;2;3;4;5"
3. "!@#$%^&*()_+;!@#$%^&*()_+;"
有没有办法在调用.split(';')
时只在;
在字母数字字符之间时拆分?
预期结果:
1. a, b, c, d, e
2. 1, 2, 3, 4, 5
3. !@#$%^&*()_+;!@#$%^&*()_+; // kept as is
这是我目前所拥有的,但在我“期望”它工作的地方并没有完全正确地分开。
.split(/[A-Za-z0-9];[A-Za-z0-9]/g);
当前结果:
1. (3) ["", ";", ";e"] // no
2. (3) ["", ";", ";5"] // no
3. ["!@#$%^&*()_+;!@#$%^&*()_+;"] // yes
只是为了更新。这不是字符串数组。以上字符串只是示例。还要澄清我期望发生的事情。
分号前面必须有数字或字母。
Yes - both characters beside the ; must be a letter or a number
a;b > a, b
1;2 > 1, 2
c;3 > c, 3
4;d > 4, d
5;6;a; > 5, 6, a
No - when either of the characters beside the ; is not a letter or a number
!;@
12$;525
aa;!$242
bbbbbb;
另一个更新anubhava 的answer 就像一个魅力,但我在这个特定的字符串中遇到了一些问题。
TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499;TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499
他的回答是/([A-Za-z0-9]+);(?=[A-Za-z0-9])/
。但是对上面的字符串使用上述正则表达式会导致
(3)
"TestTEST!@#$%^&*()_+|":?><,./;'[]\=-this is a long text.test ",
"123455899949949494949499499",
"TestTEST!@#$%^&*()_+|":?><,./;'[]\=-this is a long text.test 123455899949949494949499499"
当预期是
"TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499"
"TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499"
【问题讨论】:
alphanumeric
字符串是哪一个
alphanumeric
表示数字或字母,对吗?所以项目 1 和 2
alphanumeric
根据谷歌是 consisting of or using both letters and numerals.
,但我在这里看不到任何这样的字符串,它有字母或数字
只需使用 for 循环,我现在正在写答案。实际上,不,我不是,hafiz 的答案是完美的,使用正则表达式
我从小就将一个字符称为alphanumeric
,无论是字母还是数字。喜欢这个guy。我希望我的例子很清楚。
【参考方案1】:
您可以使用正负lookaheads 来确保分号前后是您想要的字符。因此,这将起作用:
let t1 = "a;b;c;d;e";
let t2 = "1;2;3;4;5";
let t3 = "!@#$%^&*()_+;!@#$%^&*()_+;";
console.log(t1.split(/(?![A-Za-z0-9]);(?=[A-Za-z0-9])/g)); // a, b, c, d, e
console.log(t2.split(/(?![A-Za-z0-9]);(?=[A-Za-z0-9])/g)); // 1, 2, 3, 4, 5
console.log(t3.split(/(?![A-Za-z0-9]);(?=[A-Za-z0-9])/g)); // !@#$%^&*()_+;!@#$%^&*()_+;
目前,您的正则表达式匹配一个字母数字字符,后跟一个分号和另一个字母数字字符。
【讨论】:
(?![A-Za-z0-9])
在这里没有意义,因为下一个字符无论如何都是分号(即非字母数字)。这也会将#;1
拆分为#, 1
,尽管根据问题它不应该拆分。
正如@anubhava 所说,当;
仅被1 个字母数字包围时,它将拆分。两者都必须是字母数字才能拆分。
我在我的问题中添加了更多细节【参考方案2】:
您会看到我在第一个数组中使用了一个“#”作为要测试的垃圾字符,但应该适用于任何非字母数字字符。我假设您的 cmets 您希望消除所有超过 1 个字符的字母数字字符串,所以这就是我尝试做的。
var strs = ["a;bbbb;c;dd;#","1;2;33;4;5","!@#$%^&*()_+;!@#$%^&*()_+;"]
for (var i = 0; i < strs.length; i++)
var str = strs[i].split(';');
for (var j=0; j < str.length; j++)
var chars = str[j];
if (chars.match(/[^A-Za-z\d]2/g))
console.log('this is our special character string '+strs[i]);
break;
if (chars.length > 1 ) continue;
var output = chars.split(/[^\s]([a-zA-Z\d]1)/);
for (var e = 0; e < output.length; e++)
var value = output[e];
if (value && value.match(/[A-Za-z\d]/g))
console.log(value);
【讨论】:
到目前为止这似乎很有希望,我现在会尝试更多的组合。12323;
变为 (3) ["123", "3", ""]
12323;!
变为 (3) ["123", "3", "!"]
这感觉真的很hacky,但你可以看看上面我编辑的东西似乎确实有效,尽管你必须重建你的数组而不是简单地拆分。【参考方案3】:
它出现在现代浏览器中 javascript 已经开始支持lookbehind。
如果是这种情况,那么您的解决方案是一个简单的前瞻和后瞻正则表达式,如下所示:
/(?<=[a-z0-9]);(?=[a-z0-9])/i
(?<=[a-z0-9])
: 断言我们在前面的位置有一个字母数字
(?=[a-z0-9])
: 断言我们在下一个位置有一个字母数字
var inputs = [`TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499488;TestTEST!@#$%^&*()_+|\":?><,.;'[]\\=-this is a long text.test 123455899949949494949499499`,
'a1;b2;c3;d4;e5;', '#;1', 'a;b;c;d;e', '1;2;3;4;5',
'!@#\$%^&*()_+;!@#\$%^&*()_+;']
const re = /(?<=[a-z0-9]);(?=[a-z0-9])/i;
for (var i=0; i<inputs.length; i++)
console.log(inputs[i].split(re))
然而,在较旧的浏览器中,Javascript 不支持后视。您可以使用捕获组而不是lookbehind 来捕获必须是字母数字的前一个字符,并使用正向lookahead 来断言分号后跟字母数字字符。
你可以使用:
var arr = str.split(/(.*?[a-z0-9]+);(?=[a-z0-9])/i).filter(Boolean)
代码演示:
var inputs = [`TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499488;TestTEST!@#$%^&*()_+|\":?><,.;'[]\\=-this is a long text.test 123455899949949494949499499`,
'a1;b2;c3;d4;e5;', '#;1', 'a;b;c;d;e', '1;2;3;4;5',
'!@#\$%^&*()_+;!@#\$%^&*()_+;']
var re = /(.*?[a-z0-9]+);(?=[a-z0-9])/i;
for (var i=0; i<inputs.length; i++)
console.log(inputs[i].split(re).filter(Boolean));
使用filter(Boolean)
过滤掉输出数组中的空结果。
【讨论】:
A1;B2;C3;D4;E5;
变为 (9) ["A", "1", "B", "2", "C", "3", "D", "4", "E5;"]
我刚刚偶然发现了一个问题。 TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499;TestTEST!@#$%^&*()_+|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499
变为 (3) ["TestTEST!@#$%^&*()_+|":?><,./;'[]\=-this is a long text.test ", "123455899949949494949499499", "TestTEST!@#$%^&*()_+|":?><,./;'[]\=-this is a long text.test 123455899949949494949499499"]
上面的字符串应该只是分成2个元素。
更新了我的问题。
我现在在外面。我会在 2 小时内更新它。以上是关于在字母数字字符之间以分号分隔的主要内容,如果未能解决你的问题,请参考以下文章