簡體   English   中英

正則表達式以匹配不同的單詞以及減號后的所有內容

[英]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) :匹配INTEXT
  • .*? :匹配一切
  • \\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根據要求的天數

https://regex101.com/r/zC8mG5/9

replace: (\d\w?\.? ?)(.*)\1
     to: \2

這適合你嗎?

這是一種非正則表達式方法,可以按預期工作:

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM