سؤال

على دوى النظام أماكن في الأساس لا فائدة القيود على ما يشكل معقول معرف.ومع ذلك ، تكون قادرة على سحب دويس من ملفات Pdf, صفحات الويب, إلخ.مفيد جدا عن استشهاد المعلومات ، إلخ.

هل هناك طريقة يمكن الاعتماد عليها لتحديد دوى في كتلة من النص دون افتراض 'doi:' البادئة ؟ (أي لغة مقبولة ، regexes المفضل ، وتجنب ايجابيات كاذبة لا بد منه)

هل كانت مفيدة؟

المحلول

حسنا, أنا حاليا استخراج آلاف دويس من شكل النص (XML) و أدركت أن بلدي النهج السابق كان عدد قليل من المشاكل ، وهي تتعلق المشفرة الكيانات زائدة الترقيم لذا ذهبت في القراءة مواصفات وهذا هو أفضل ما يمكن أن تأتي مع.


على دوي البادئة يتألف من دليل مؤشر تليها المسجل رمز.هذين العنصرين يجب أن تكون مفصولة كامل وقف (الفترة).

الدليل المؤشر يجب أن يكون "10".الدليل المؤشر يميز مجموعة كاملة من سلاسل الأحرف (البادئة واللاحقة) كما الرقمية معرفات الكائنات ضمن قرار نظام.

من السهل بما فيه الكفاية الأولية \b يمنع الولايات المتحدة من "مطابقة" أ "دوي" التي لا تبدأ 10.:

$pattern = '\b(10[.]';

العنصر الثاني من دوي البادئة يكون المسجل رمز.على المسجل هو رمز فريد من نوعه string تعيين المسجل.

أيضا, كل تعيين المسجل رمز الرقمية, و لا يقل عن 4 أرقام طويلة, لذلك:

$pattern = '\b(10[.][0-9]{4,}';

المسجل قد يكون رمز ينقسم إلى عناصر فرعية على الإدارية الراحة إذا رغبت في ذلك.كل عنصر من المسجل رمز يجب أن يسبقه وقف كامل.

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*';

على دوي جملة تتكون من دوي البادئة و دوي لاحقة يفصل بينهما خط مائل.

ولكن هذا ليس ضروريا على الاطلاق ، القسم 2.2.3 الدول التي لها لاحقة يمكن أن تستخدم أنظمة الاتفاقيات الأخرى (مثل 10.1000.123456 بدلا من 10.1000/123456) ، ولكن دعونا قطع بعض الركود.

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/';

على دوى اسم حالة الأحرف و يمكن أن تتضمن أي للطباعة الشخصيات القانونية من رسم أحرف Unicode.على دوي لاحقة تتكون من سلسلة أحرف من أي طول اختاره المسجل.كل لاحقة يجب أن تكون فريدة من نوعها البادئة عنصر تسبق ذلك.فريدة من نوعها لاحقة يمكن أن يكون رقم تسلسلي ، أو قد تتضمن معرف الناتجة عن أو استنادا إلى نظام آخر.

الآن هذا هو المكان الذي تحصل عليه اصعب من كل دويس يجب معالجتها ، رأيت الأحرف التالية (إلى جانب [0-9a-zA-Z] بالطبع) في اللواحق: .-()/:- -- لذلك ، في حين أنه لا وجود له ، دوى 10.1016.12.31/nature.S0735-1097(98)2000/12/31/34:7-7 من المعقول تماما.

الخيار المنطقي استخدام \S أو [[:graph:]] PCRE POSIX الدرجة, لذا دعونا نفعل ذلك:

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/\S+'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/[[:graph:]]+';

الآن لدينا مشكلة صعبة ، [[:graph:]] فئة السوبر مجموعة من [[:punct:]] الطبقة التي تضم شخصيات العثور عليها بسهولة في النص الحر أو أي لغة الترميز: "'&<> من بين أمور أخرى.

يتيح مجرد تصفية العلامات منها الآن باستخدام سلبي lookahead:

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+';

ما سبق يجب أن تغطي المشفرة الكيانات (&) ، ويعزو ونقلت (["']) و فتح / إغلاق علامات ([<>]).

على عكس اللغات الترميزية, حر النص عادة لا تستخدم أحرف علامات التنقيط إلا أنها يحدها واحد على الأقل مساحة أو توضع في نهاية الجملة, فعلى سبيل المثال:

هذا هو عملية طويلة DOI: 10.1016.12.31/nature.S0735-1097(98)2000/12/31/34:7-7!!!

الحل هنا هو أن تغمض التقاط لدينا مجموعة وتأكيد كلمة أخرى الحدود:

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+)\b'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+)\b';

و voilá, هنا هو العرض.

نصائح أخرى

@سيلاس العقل التحقق هو فكرة جيدة.ومع ذلك ، فإن regex لا تغطي جميع دويس.العنصر الأول أن (حاليا) 10 و العنصر الثاني أن (حاليا) تكون رقمية ، ولكن العنصر الثالث هو بالكاد يقتصر في كل شيء:

"القانونية الشخصيات القانونية الرسم أحرف Unicode.ويستثنى من هذا تحديدا سيطرة الطابع يتراوح 0x00-0x1F و 0x80-0x9F..."

وحيث ان المشكلة الحقيقية تكمن.في الممارسة العملية ، لم أر بيضاء تستخدم ، ولكن المواصفات على وجه التحديد تسمح بذلك.في الأساس هناك لا يبدو أن يكون وسيلة معقولة الكشف عن نهاية من دوي.

CrossRef لديه توصية, التي تم اختبارها بنجاح على 99.3% من دويس:

/^10.\d{4,9}/[-._;()/:A-Z0-9]+$/i

أنا متأكد من انها ليست فائقة المفيد المرجع في هذه النقطة, ولكن فكرت بعد ما أحاول في حالة أي شخص آخر مثلي الزلات هذا:

(10.(\d)+/(\S)+)

هذه المباريات:"10 دوت عدد القطع أي شيء-لا-بيضاء"

ولكن بالنسبة لي استخدم (كشط HTML), كانت هذه الحقائق كاذبة ايجابيات لذا كان علي أن المباراة المذكورة أعلاه بالإضافة إلى التخلص من يقتبس أكبر من/أقل من:

(10.(\d)+/([^(\s\>\"\<)])+)

ما زلت اختبار هذه ، ولكن أنا أشعر بالأمل حتى الآن.

هنا هو بلدي الذهاب في ذلك:

(10[.][0-9]{4,}[^\s"/<>]*/[^\s"<>]+)

واثنين من صالح حافة الحالات التي لا تفشل ، ولكن البعض الآخر يبدو أن تفعل:

أيضا, صحيح يتجاهل بعض falsy (X|HT)مل الاشياء مثل:

  • <geo coords="10.4515260,51.1656910"></geo>

هذا هو حقا القديمة و الإجابة على السؤال, ولكن هنا محتمل آخر بديل.

\b10\.(\d+\.*)+[\/](([^\s\.])+\.*)+\b

هذا يفترض أن المساحة البيضاء ليست جزءا من دوي.

لم يتم اختبار هذا عن ايجابيات كاذبة ، ولكن يبدو أن تكون قادرة على العثور على كل حافة الحالات المذكورة في هذه الصفحة.

التالية regex ينبغي القيام بهذه المهمة (بيرل regex الجملة):

/(10\.\d+\/\d+)/

هل يمكن أن تفعل بعض إضافية التعقل التحقق عن طريق فتح url

http://hdl.handle.net/<doi>

و

http://dx.doi.org/<doi>

أين هو المرشح دوي,

والاختبار الذي كنت أ) الحصول على 200 موافق حالة http ، ب) عاد الصفحة ليست "دوي" لم يتم العثور على الصفحة للحصول على الخدمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top