使用更合适的示例字符串更新了问题
有这样的字符串:
Name I, Some-Thing A, More BC (2016) Example: A string title. Publication. 12:123-54
Name I, Some-Thing A, More BC, et al. (2016) Example: A string title? Publication. 12:123-54
Name I, Some-Thing A, More BC: Example: A string title. Publication 2016; 12: 123-54
Name I, Some-Thing A, More BC: Example: A string title. Publication 2016; 12: 123
Name I, Some-Thing A, More BC (2016): Example: A string title. Publication 12, 123-54
Name I, Some-Thing A, More BC (2016): Example: A string title. Publication 12 (6), 123-54
Name I, Some-Thing A, More BC: Example: A string title. Publication. 2016 June;12(6):123-54. Ignore this
现在我正在尝试提取它们的部分以获得结果:
1: Name I, Some-Thing A, More BC || Name I, Some-Thing A, More BC, et al.
2: 2016
3: Example: A string title? || Example: A string title
4: Publication
5: 12
6: 123-54 || 123
这是我到目前为止所得到的:
/([\w-]+ [A-Z]{1,3}(?:, [\w-]+ [A-Z]{1,3})*(?:, et al\.)*)|\((\d{4})\)?|([\w:]+[\w ]+(?=\.|\?|$))|(\d+(?=:))|([\d-]+)/g
https://regex101.com/r/wB3wU4/2
感谢 anubhava 和 Jan 到目前为止。
但有了这个我没有得到所有 Publication ,在最后一个字符串中我想忽略pagenumber之后的所有内容,我需要忽略pagenumber前面的括号(如果有的话)一个)。
对我来说,第二个问题是如何使用此数据进行正确处理,因为匹配的位置可能不同。示例:通常匹配[2]应为year
,但对于第3个字符串,情况并非如此。所以结果搞得一团糟: - (
答案 0 :(得分:4)
如果您的示例输入是您通常会遇到的常见字符串的指示符,您可以将此概括一点:
// Split the string based on parentheses, periods, question-marks and colons
// along with any leading or trailing spaces (i.e. trimming)
var matches = input.split(/\s*[().?:]\s*/);
从可读性和维护的角度来看,正则表达式通常是噩梦,所以如果可以简化它们,我会推荐它。
示例强>
var input = "Name I, Some A, More BC (2016) A string title. Publication. 12:123-54";
var matches = input.split(/\s*[()?.:]\s*/);
for(var i = 0; i < matches.length; i++){
console.log('[' + i +']:' + ' ' + matches[i]);
}
答案 1 :(得分:2)
你去了:
([^()]+)\((\d+)\)\s*([^.]+)[.\s]*([^.]+)[.\s]*(\d+):([-\d]+)
捕获组编号与您的编号相对应,请参阅a demo on regex101.com。
答案 2 :(得分:2)
我把帽子戴在戒指上的时间。这就是我想出的:
^(.*?)\s*(?:\(((?:19|20)\d\d)\)|:)[\s:]*(.*?[?.!])\s*([\w\s]+?)\.?\s*(?:((?:19|20)\d\d)(?:\s+\w+)?)?[.;\s]*(\d+)\s*(?:\(\d+\))?[,:\s]+(\d+(?:-\d+)?)[^\d]*$
由于复杂性,我不会尝试在此处解释正则表达式的每一部分,但请检查指向regex101的链接,您将在右侧窗格中看到解释。
但我会尝试解释它的要点。这取决于我不确定的一些事实,但是......
从字符串的开头
:
)。这限制了一年到二十或二十一世纪的匹配。然后从后面:
number dash number
形式,后面的部分是可选的。12
部分是一个数字,可选地前面有.
,;
或空格,后跟括号内的可选数字。括号可以选择以空格开头。然后整个部分后跟至少一个,
,:
或空格。12
部分可选择以一年开头,然后可选择后跟一个月(扔掉)。在字符串的开头和结尾之间,从第一部分开始,“句子”被捕获以标点符号结尾(.
,?
或{{ 1}})。之后是第二个“句子” - !
部分。
这为我们提供了以下捕获组:
Publication
Publication
part 12
part 即年份在第2组或 5。
感觉非常脆弱,但它可能会为您完成工作。 ;)
修改强>
我做了一个JS剪辑来说明:(使用全屏)
123-54
修改强>
评论:标题以括号或冒号OR点结束一年。
我还没有完全掌握不同部分是什么,但我认为在这种情况下它是我们谈论的第一个领域。 (示例中的第三个字段结束“字符串标题”...)其当前表单中的正则表达式处理年份和冒号。因此,要将 dot 添加到字段终止符,您可以将问题var theStrings = [
'Name I, Some-Thing A, More BC (2016) Example: A string title. Publication. 12:123-54',
'Name I, Some-Thing A, More BC, et al. (2016) Example: A string title? Publication. 12:123-54',
'Name I, Some-Thing A, More BC: Example: A string title. Publication 2016; 12: 123-54',
'Name I, Some-Thing A, More BC: Example: A string title. Publication 2016; 12: 123',
'Name I, Some-Thing A, More BC (2016): Example: A string title. Publication 12, 123-54',
'Name I, Some-Thing A, More BC (2016): Example: A string title. Publication 12 (6), 123-54',
'Name I, Some-Thing A, More BC: Example: A string title. Publication. 2016 June;12(6):123-54. Ignore this',
'Name I, Some-Thing A, More BC (2050) Example: A string title. Placeholder. 55:123-54',
'Name I, Some-Thing A, More BC, et al. (2016) Example: A string title? Word. 22:123-54',
'Name: Example: A string title. Variable 2014; 31: 123-54',
'This can basically be anything!: Example: A string title. Publication 100 2058; 789: 123',
'Name I, Some-Thing A, More BC (1998): Example: A string title. What Ever 4, 123-54',
'Name I, Some-Thing A, More BC (2016): Example: A string title. Journey of 2000 miles 54 (6), 123-54',
'Name I, Some-Thing A, More BC: Example: A string title. Some Words. 1999 June;1(6):123-54. Ignore this'
],
re = /^(.*?)\s*(?:\(((?:19|20)\d\d)\)|:)[\s:]*(.*?[?.!])\s*([\w\s]+?)\.?\s*(?:((?:19|20)\d\d)(?:\s+\w+)?)?[.;\s]*(\d+)\s*(?:\(\d+\))?[,:\s]+(\d+(?:-\d+)?)[^\d]*$/,
res,
i, j
output = '<style>caption {background-color: blue; color: white;} th {background-color: lightblue;}</style>';
for (i = 0; i < theStrings.length; i++) {
res = theStrings[i].match(re);
output += '<table border="1" style="width:100%">';
output += '<tr>';
output += '<caption>The string "' + theStrings[i] + '" ends up as:</caption>';
output += '<tr><th style="width:30%">Title 1</th><th style="width:10%">Year</th><th style="width:30%">Title 2</th><th style="width:10%">Value 4</th><th style="width:10%">Value 5</th><th style="width:10%">Value 6</th></tr>';
output += '<td>' + res[1] + '</td>';
output += '<td>' + (res[2] ? res[2] : res[5]) + '</td>';
output += '<td>' + res[3] + '</td>';
output += '<td>' + res[4] + '</td>';
output += '<td>' + res[6] + '</td>';
output += '<td>' + res[7] + '</td></tr></table><br/>';
}
document.write(output);
更改为:
,允许:
[:.]
答案 3 :(得分:1)
我使用以下正则表达式:
^([A-Za-z-]+ [A-Z]{1,3}(?:, [A-Za-z-]+ [A-Z]{1,3})*(?:, et al\.)?):? (?:\((\d{4})\):? )?([A-Za-z\:\?\. ]+[A-Za-z\?])\.? ([A-Za-z]+)\.? (?:([0-9]+)[A-Za-z ]*; ?)?(\d+) ?(?:\(\d+\))?[\:,] ?([0-9-]+)
由于year
可以在不同的地方进行交换,因此我使用此代码始终获取正确的year
:
var year = matches[2] || matches[5];
您可以在this fiddle中查看整个脚本。
这个正则表达式会给我以下输出,我认为这些是您正在寻找的:
&#39;姓名I,Some A,More BC(2016)字符串标题。插图。 12:123-54&#39;
1: "Name I, Some A, More BC"
2: "2016"
3: "A string title"
4: "Illustration"
5: "12"
6: "123-54"
&#39;姓名I,Some-Thing A,更多BC(2016)示例:字符串标题。出版物。 12:123-54&#39;
1: "Name I, Some-Thing A, More BC"
2: "2016"
3: "Example: A string title"
4: "Publication"
5: "12"
6: "123-54"
&#39;姓名I,Some-Thing A,More BC,et al。 (2016)示例:字符串标题?出版物。 12:123-54&#39;
1: "Name I, Some-Thing A, More BC, et al."
2: "2016"
3: "Example: A string title?"
4: "Publication"
5: "12"
6: "123-54"
&#39;姓名I,Some-Thing A,更多BC:示例:字符串标题。插图2016; 12:123-54&#39;
1: "Name I, Some-Thing A, More BC"
2: "2016"
3: "Example: A string title"
4: "Illustration"
5: "12"
6: "123-54"
&#39;姓名I,Some-Thing A,更多BC:示例:字符串标题。 2016年出版物; 12:123&#39;
1: "Name I, Some-Thing A, More BC"
2: "2016"
3: "Example: A string title"
4: "Publication"
5: "12"
6: "123"
&#39;姓名I,Some-Thing A,更多BC(2016):示例:字符串标题。出版物12,123-54&#39;
1: "Name I, Some-Thing A, More BC"
2: "2016"
3: "Example: A string title"
4: "Publication"
5: "12"
6: "123-54"
&#39;姓名I,Some-Thing A,更多BC(2016):示例:字符串标题。出版物12(6),123-54&#39;
1: "Name I, Some-Thing A, More BC"
2: "2016"
3: "Example: A string title"
4: "Publication"
5: "12"
6: "123-54"
&#39;姓名I,Some-Thing A,更多BC:示例:字符串标题。出版物。 2016年6月; 12(6):123-54。忽略这个&#39;
1: "Name I, Some-Thing A, More BC"
2: "2016"
3: "Example: A string title"
4: "Publication"
5: "12"
6: "123-54"
答案 4 :(得分:0)
您可以使用这个笨拙的正则表达式捕获各种组件:
/^((?:,? *[A-Za-z.-]+ [A-Za-z]{1,3})+)[ :.,]+(?:\((\d+)\)[ :]+)?([a-zA-Z]+: [a-zA-Z ]+[?]?)[. ]+([A-Za-z]+)[. ;\dA-Za-z]+?(\d+)(?:[:,]| *\()[: \d,)]*?(\d+(?:-\d+)?)(?:[ .]|$)/gm
答案 5 :(得分:0)
有很多答案,所以我也应该提供一些比较
^([\w-]+ [A-Z]{1,3}(?:, [\w-]+ [a-zA-Z]{1,3}\.?)*)[ :](?:\((\d+)\)| ?([\w]+)):? ?([ \w]+)[.:?]? ?([ \w]+)?[.:?]? ?([A-Za-z]+)?[.:?]? ?([\d]+) ?([a-zA-Z]+)?[,;:]? ?(?:\(([\d-]+)\),?|([\d-]+)):? ?(?:\((\d+)\)[,:]|([\d-]+))? ?([\d-]+)?
仅供参考,它的长度为232个字符。
如果输入与原始帖子中的输入类似,或者如您在某些评论中所述的那样指定,则确实有效。 Live demo
我不认为它是正则表达式。它使用语法,但不仅仅是编程if / else条件。这就像爬梯子可能有一些破碎的梯级。但这是解决问题所需的一种方式。
我不知道。这是你的选择。但是我会对满足您需求的答案进行基准测试。
Name I, Some-Thing A, More BC (2016) Example: A string title. Publication. 12:123-54
Name I, Some-Thing A, More BC, et al. (2016) Example: A string title? Publication. 12:123-54
Name I, Some-Thing A, More BC: Example: A string title. Publication 2016; 12: 123-54
Name I, Some-Thing A, More BC: Example: A string title. Publication 2016; 12: 123
Name I, Some-Thing A, More BC (2016): Example: A string title. Publication 12, 123-54
Name I, Some-Thing A, More BC (2016): Example: A string title. Publication 12 (6), 123-54
Name I, Some-Thing A, More BC: Example: A string title. Publication. 2016 June;12(6):123-54. Ignore this
Name I, Some-Thing A, More BC (2050) Example: A string title. Placeholder. 55:123-54
Name I, Some-Thing A, More BC, et al. (2016) Example: A string title? Word. 22:123-54
迭代次数:50 x 1000
标志:multi-line
@ HiDeo的RegEx:
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 9
Elapsed Time: 10.75 s, 10753.42 ms, 10753415 µs
@ anubhava的RegEx:
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 9
Elapsed Time: 9.28 s, 9277.62 ms, 9277621 µs
@ ClasG&#39; RegEx:
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 9
Elapsed Time: 8.86 s, 8864.05 ms, 8864050 µs
@ revo的RegEx:
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 9
Elapsed Time: 7.02 s, 7024.97 ms, 7024972 µs
如图所示,所有表演时间都非常接近。所以你不会很难选择一个。
感谢@sln节省时间和最近我开始合作的精彩软件RegexFormat。