[英]regex to match different words and everything after minus ending
我有几种鼻塞线的变体,我需要弄清楚它的中间部分。 幸运的是,该模式只有几个变体,但我无法使其适用于所有变体。
1 INT. HIGH SCHOOL - DAY 1
EXT. HOUSE - NIGHT
2A INT. HOSPITAL - NIGHT 2A
3. EXT. AIRPORT - DAY 3.
4B. INT. MALL - NIGHT 4B.
我想要实现的是使字符串从INT或EXT一直到最后一个单词,不包括数字/字母或点组合。 我想要这个:
INT. HIGH SCHOOL - DAY
EXT. HOUSE - NIGHT
INT. HOSPITAL - NIGHT
EXT. AIRPORT - DAY
INT. MALL - NIGHT
正则表达式中有没有一种干净的方法
我得到的最好的是使用此:
@"(?:INT|EXT:).*$")
不幸的是,它仅返回从INT开始直到结尾的字符串,但不适用于EXT,也不会删除结尾的数字/字母或点。
您不需要使用Regex-一种有效的linq解决方案:
var str = "1 INT.HIGH SCHOOL -DAY 1";
var newStr = String.Join(" ",str.Split().Where(s => !s.Any(c => Char.IsDigit(c)))).Trim();
Console.WriteLine(newStr); // INT.HIGH SCHOOL -DAY
你可以试试这个:
((?:INT|EXT).*?)\s*\S*$
(?:INT|EXT)
:匹配INT
或EXT
.*?
:匹配一切 \\s*\\S*$
:匹配行的最后一个字符(但是不包含在de匹配部分内) 这可以正常工作并提供您所需的结果:
@".*((?:INT. |EXT. )[A-Za-z\\. \\-]+).*$"
使用方法如下:
var vMatch = Regex.Match("1 INT. HIGH SCHOOL - DAY 1", @".*((?:INT. |EXT. )[A-Za-z\. \-]+).*$");
var extracted = vMatch.Groups[1].Value.Trim();
extracted
包含INT. HIGH SCHOOL - DAY
INT. HIGH SCHOOL - DAY
根据要求的天数
这是一种非正则表达式方法,可以按预期工作:
string[] prefixes = { "INT", "EXT" };
for (int i = 0; i < list.Count; i++)
{
string oldS = list[i].Trim();
int indexOflastSpace = oldS.LastIndexOf(' ');
int endIndex = oldS.Length - 1;
if(indexOflastSpace >= 0)
{
string rest = oldS.Substring(indexOflastSpace).TrimStart();
// starts the last token with a digit?
if(char.IsDigit(rest[0]))
endIndex = indexOflastSpace;
}
int start = 0;
int indexOfAnyPrefix = prefixes
.Select(p => oldS.IndexOf(p, StringComparison.InvariantCultureIgnoreCase))
.Where(index => index >= 0)
.DefaultIfEmpty(-1)
.First();
if(indexOfAnyPrefix > 0)
start = indexOfAnyPrefix;
string newS = oldS.Substring(start, endIndex - start);
list[i] = newS;
}
Regex和Linq的替代方法( 在线尝试 ):
string s = @"1 INT. HIGH SCHOOL - DAY 1
EXT. HOUSE - NIGHT
2A INT. HOSPITAL - NIGHT 2A
3. EXT. AIRPORT - DAY 3.
4B. INT. MALL - NIGHT 4B.";
const string startWithNum = @"^\d";
foreach (var line in s.Split('\r', '\n').Select(item => new List<string>(item.Split(' '))))
{
if (Regex.IsMatch(line[0], startWithNum))
line.RemoveAt(0);
if (Regex.IsMatch(line[line.Count - 1], startWithNum))
line.RemoveAt(line.Count - 1);
Console.WriteLine(String.Join(" ", line));
}
输出:
INT. HIGH SCHOOL - DAY
EXT. HOUSE - NIGHT
INT. HOSPITAL - NIGHT
EXT. AIRPORT - DAY
INT. MALL - NIGHT
这就是我的方法。 我喜欢使用IgnorePatternWhitespace选项来提高表达式的可读性。
我将数据显示为一个块,但是如果逐行处理它也可以使用。
var text = "1 INT. HIGH SCHOOL - DAY 1" + Environment.NewLine;
text += "EXT. HOUSE - NIGHT" + Environment.NewLine;
text += "INT. HOSPITAL - NIGHT 2A" + Environment.NewLine;
text += "3. EXT. AIRPORT - DAY 3." + Environment.NewLine;
text += "4B. INT. MALL - NIGHT 4B." + Environment.NewLine;
var options = RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace;
var regex = new Regex("^ .*? (?<slug> (?:INT|EXT)\\. .*?) (?:\\s+?\\d.*?)? $", options );
var matches = regex.Matches( text );
foreach( Match m in matches ){
Console.WriteLine( "|" + m.Groups["slug"].Value + "|" );
}
产生:
|INT. HIGH SCHOOL - DAY|
|EXT. HOUSE - NIGHT |
|INT. HOSPITAL - NIGHT|
|EXT. AIRPORT - DAY|
|INT. MALL - NIGHT|
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.